题目链接:​​http://poj.org/problem?id=3509​​​
题意:给你一个n*n的数字矩阵,那么他就会有(n+1)/2个环,你可以旋转这些环,现在问你,能否通过旋转这些环使得这个矩阵变得有序
解析:这里主要判断的是,环是否合法,如果环上的数字不对,那么你怎么旋转都转不出答案,那么我们可以把所有的环记录下来,和排好序的矩阵的环进行配对,如果配对成功就输出YES,否则NO

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
#include <cmath>
#include <map>
using namespace std;
const int maxn = 1e5+100;
const int inf = 0x7ffffff;
int a[1005][1005];
int ans[1005][1005];
int huan[1005][1005];
int anshuan[1005][1005];
int main(void)
{
int n;
int case_t = 1;
while(~scanf("%d",&n)&&n)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
}
int cnt = 1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
ans[i][j] = cnt++;
}
int tmp = (n+1)/2;
int t1 = 1,t2 = n;
int t3 = 1,t4 = n;
int flag = 0;
for(int i=1;i<=tmp;i++)
{
int cnt1 = 0;
int cnt2 = 0;
for(int j=t1;j<=t2;j++)
{
huan[i][cnt1++] = a[t1][j];
anshuan[i][cnt2++] = ans[t1][j];
}
t1++;
for(int j=t1;j<=t4;j++)
{
huan[i][cnt1++] = a[j][t4];
anshuan[i][cnt2++] = ans[j][t4];
}
t4--;
for(int j=t4;j>=t3;j--)
{
huan[i][cnt1++] = a[t2][j];
anshuan[i][cnt2++] = ans[t2][j];
}
t2--;
for(int j=t2;j>=t1;j--)
{
huan[i][cnt1++] = a[j][t3];
anshuan[i][cnt2++] = ans[j][t3];
}
t3++;
int k = 0;
int pp = i+(i-1)*n;
for(;k<cnt1;k++)
{
if(huan[i][k]==pp)
break;
}
for(int j=0;j<cnt2;j++)
{
if(anshuan[i][j]!=huan[i][k])
{
flag = 1;
break;
}
k = (k+1)%cnt2;
}
if(flag)
break;
}
if(flag)
printf("%d. NO\n",case_t++);
else
printf("%d. YES\n",case_t++);
}
return 0;
}