题解:SP4568 ANARC07C - Rotating Rings

题意

当一个 \(N\times N\) 矩阵中的元素刚好包含 \(1\sim N\times N\)\(N \times N\) 个值,且按行从左到右,换行从左开始的顺序填入一个数组,这个数组是按 \(1\sim N\times N\) 排列的时,这个矩阵被称为有序的。同时一个 \(N\times N\) 的矩阵被分为 \(\lceil \frac{N}{2}\rceil\) 个环,如下图,同色、同数字的就是一个环:

转动环就是按照行从左到右,换行从左开始的顺序填入一个数组,将这个数组的开头丢到结尾去,然后再按顺序填回去。

注意

题面中的 \(1\le N \le 100\) 是错误的,实测 \(N > 100\)link

思路

一个很简单但有一点细节的模拟。

先预处理出一个有序的矩阵,然后拆出环里的元素,丢到 \(\lceil \frac{N}{2}\rceil\) 个 vector 里,然后再在输入的矩阵拆出这么几个环,然后在第 \(i\) 个环上旋转 \([n-(i-1)\times 2-1]\times 4\) 次,边转边与有序的环比较,如果有相等就到下一个环,一直没有就可以退出循环输出 NO,否则所有环都有相等就输出 YES

代码

//by _maple_leaf_ uid:964876
const int N=1145;
int cnt;
int n,m;
bool f;
int mp[N][N];
int a[N][N];
queue<int>s[N>>1];
bool fff[N*N];
signed main(){
    while(1){
        memset(fff,0,sizeof fff);
        cnt++;
        n=read();
        if(!n)return 0;
        f=1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                a[i][j]=read();
            }
        }
        for(int i=1;i<=n*n;i++)mp[(int)ceil((double)i/n)][(i-1)%n+1]=i;//填出有序矩阵
        m=(n+1)>>1;
        for(int i=1;i<=m;i++){
            while(!s[i].empty())s[i].pop();
            int h1=i,h2=n-i+1,l1=i,l2=n-i+1;
            for(int j=l1;j<=l2;j++)s[i].push(mp[h1][j]);
            for(int j=h1+1;j<=h2-1;j++)s[i].push(mp[j][l2]);
            if(h2!=h1)for(int j=l2;j>=l1;j--)s[i].push(mp[h2][j]);
            if(l2!=l1)for(int j=h2-1;j>=h1+1;j--)s[i].push(mp[j][l1]);//拆出有序矩阵的第i个环
        }
        for(int i=1;i<=m;i++){
            int h1=i,h2=n-i+1,l1=i,l2=n-i+1,temp=0;
            queue<int>v;
            while(!v.empty())v.pop();
            for(int j=l1;j<=l2;j++){
                v.push(a[h1][j]);
                temp++;
            }
            for(int j=h1+1;j<=h2-1;j++){
                v.push(a[j][l2]);
                temp++;
            }
            if(h1!=h2){
                for(int j=l2;j>=l1;j--){
                    v.push(a[h2][j]);
                    temp++;
                }
            }
            if(l2!=l1){
                for(int j=h2-1;j>=h1+1;j--){
                    v.push(a[j][l1]);
                    temp++;
                }
            }//拆下第i个环
            bool t=0;
            while(temp--){
                if(v==s[i]){//判断
                    t=1;
                    break;
                }
                v.push(v.front());//转
                v.pop();
            }if(!t){//无解,退出循环
                f=0;
                break;
            }
        }write(cnt);
        putchar('.');
        putchar(' ');
        if(f)puts("YES");
        else puts("NO");
    }
#if DEBUG
    debug();
#endif
    return 0;
}//~*完结撒花*~
#if DEBUG
bool Memory_end;
void debug(){
    cerr<<"Time: "<<clock()<<" ms\n";
    cerr<<fixed<<setprecision(6)<<"Memory: "<<abs(&Memory_start-&Memory_end)/1024.0/1024.0<<" MB";
}
#endif
posted @ 2025-02-11 18:45  BriskCube  阅读(17)  评论(0)    收藏  举报