Gym 100496A Avangard Latin Squares(矩阵游戏)

题意:输入一个n,表示在n*n的矩阵中填1~n,使每行每列以及所有正对角线所有反对角线均出现1~n一次。若存在,输出Yes和矩阵,否则输出No;

思路:比赛的时候没思路。将1~n换为0~n较好处理一些。先只考虑0的位置,每行将0向一个方向移动固定格子数,枚举所需的移动步数,

        若满足条件(无同行同列同对角线)则Yes,1~n以相同步数移动;否则为No;

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,flag;
int pos[5050],pre[5050];
int main()
{
    freopen("avangard.in","r",stdin);
    freopen("avangard.out","w",stdout);
    int i,j,k,cnt;
    while(scanf("%d",&n)!=EOF)
    {
        cnt=0;
        for(i=2;i<n-1;i++)//枚举移动格数
        {
            flag=1;
            for(j=1;j<n;j++)//枚举移动次数
            {
                cnt=i*j%n;//0所在位置
                if(cnt==0) flag=0;//同列
                else if(cnt==j) flag=0;//正对角线上
                else if((cnt+j)==n) flag=0;//反对角线上
            }
            if(flag==1)
            {
                cnt=i;break;
            }
        }
        if(n==1)
        {
            printf("Yes
");printf("1
");continue;
        }
        for(i=1;i<=n;i++) pos[i]=i;
        if(!flag) printf("No
");
        else{
            printf("Yes
");
            for(i=1;i<=n;i++)
            {
                for(j=1;j<=n;j++) pre[pos[j]]=j;
                for(j=1;j<=n;j++)
                {
                    if(j==1) printf("%d",pre[j]);
                    else printf(" %d",pre[j]);
                }printf("
");
                for(j=1;j<=n;j++)
                {
                    pos[j]+=cnt;//位置右移,即数左移
                    if(pos[j]>n) pos[j]-=n;
                }
            }
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/dashuzhilin/p/4643829.html