题解:B4226 [常州市赛 2024] 密码

· · 题解

题目:https://www.luogu.com.cn/problem/B4226

一道经典的模版题

如果新手们看不懂大佬的方法推荐这个。

思路:

先把输入的矩阵转化为一个字符串,再把字符串转化为另一个矩阵。

处理字符组

我采用的是数学的方法,观察到每一斜排的横坐标加纵坐标为定值,所以可再主函数中采用直接循环的方法处理字符组。

代码如下:

for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++){
            if(i+j<=n+1){//左上部分(包括最中间)
                if((i+j)%2==0)
                    b[sum(i+j-2)+j]=a[i][j];
                else
                    b[sum(i+j-2)+i]=a[i][j];
            }
            else{//右下部分
                if((i+j)%2==0)
                    b[n*n-sum(2*n-i-j)-n+j]=a[i][j];
                else
                    b[n*n-sum(2*n-i-j)-n+i]=a[i][j];
            }
        }

然后处理转换后的矩阵

这次采用模拟的方法,其中m是转换的序数,flag是方向指针,visit是访问数组。

看代码吧

int flag=1;
int x=1,y=1,n,m=1;
bool visit[501][501];
char a[501][501],b[501*501],c[501][501];//矩阵与字符组
void change(){
    c[x][y]=b[m];//赋值
    switch(flag){
        case 1:
            if(visit[x+1][y]||x==n){
                flag++;
                y++;
            }
            else{
                x++;
            }
            break;
        case 2:
            if(visit[x][y+1]||y==n){
                flag++;
                x--;
            }
            else{
                y++;
            }
            break;
        case 3:
            if(visit[x-1][y]||x==1){
                flag++;
                y--;
            }
            else{
                x--;
            }
            break;
        case 4:
            if(visit[x][y-1]||y==1){
                flag=1;
                x++;
            }
            else{
                y--;
            }
            break;
    }
    visit[x][y]=1;//将(x,y)设为访问过
    m++;//轮到下一个
    return; 
}

但是,注意:一次自定义只能复制一次。

最后放一下完整 AC 代码:

#include<bits/stdc++.h>//万能头不解释
using namespace std;
int flag=1;
int x=1,y=1,n,m=1;
bool visit[501][501];
char a[501][501],b[501*501],c[501][501];//矩阵与字符组
void change(){
    c[x][y]=b[m];
    switch(flag){
        case 1:
            if(visit[x+1][y]||x==n){
                flag++;
                y++;
            }
            else{
                x++;
            }
            break;
        case 2:
            if(visit[x][y+1]||y==n){
                flag++;
                x--;
            }
            else{
                y++;
            }
            break;
        case 3:
            if(visit[x-1][y]||x==1){
                flag++;
                y--;
            }
            else{
                x--;
            }
            break;
        case 4:
            if(visit[x][y-1]||y==1){
                flag=1;
                x++;
            }
            else{
                y--;
            }
            break;
    }
    visit[x][y]=1;//将(x,y)设为访问过
    m++;//轮到下一个
    return; 
}
int sum(int number){
    return number*(number+1)/2;
}
int main(){
    visit[1][1]=1;//赋初始值
    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            cin>>a[i][j];//输入数据
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            if(i+j<=n+1){
                if((i+j)%2==0)
                    b[sum(i+j-2)+j]=a[i][j];
                else
                    b[sum(i+j-2)+i]=a[i][j];
            }
            else{
                if((i+j)%2==0)
                    b[n*n-sum(2*n-i-j)-n+j]=a[i][j];
                else
                    b[n*n-sum(2*n-i-j)-n+i]=a[i][j];
            }
        }
    for(int i=1;i<=n*n;i++)
            change();//记得是n²不是n!!!
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++)
            cout<<c[j][i];//输出
        cout<<"\n";
    }
    return 0;
}

如果你看懂了以上全部内容,AC 就离你不远了。