2 条题解

  • 3
    @ 2024-8-1 15:40:26

    虽然非常牛波一的申哥已经发了一次题解,但是他的代码都是挤在main函数里,可能导致有的同学理解起来有些困难,特此水一发自己的

    Ps:因为没看清题卡了好久

    #include<bits/stdc++.h> 
    using namespace std;
    
    typedef long long ll;
    const ll N = 3e2 + 10;
    
    ll n, m, num[N][N], dui[N][N], tmp[N][N], res[N][N];
    char code[N][N];
    string ans;
    
    bool isPrime(ll x){             // 判断是否为质数
        if (x == 2 || x == 3 || x == 5 || x == 7) return true;
        return false;
    }
    
    bool isUpper(char x){           // 判断是否大写
        return (x >= 'A' && x <= 'Z');
    }
    
    bool isCorre(ll x, ll y){       // 判断该区域是否有效,x和 y是字母表中要枚举的矩阵的开始下标
        ll x2 = x + n - 1, y2 = y + n - 1;
    
        if (num[1][1] == dui[x][y] && num[1][n] == dui[x][y2] && num[n][1] == dui[x2][y] && num[n][n] == dui[x2][y2]) return true;
        return false;
    }
    
    void turnRight(ll cnt){         // 把数字表旋转,cnt是要转几次
        while (cnt --){
            for (ll i = 1; i <= n; i ++)
                for (ll j = 1; j <= n; j ++)
                    tmp[i][j] = num[n - j + 1][i];
            
            for (ll i = 1; i <= n; i ++)
                for (ll j = 1; j <= n; j ++)
                    num[i][j] = tmp[i][j];
        }
    }
    
    ll countUpper(ll x, ll y){      // 统计 4个角的大写字母数量
        ll x2 = x + n - 1, y2 = y + n - 1;
    
        return ((isUpper(code[x][y])) + (isUpper(code[x][y2])) + (isUpper(code[x2][y])) + (isUpper(code[x2][y2])));
    }
    
    void decode(ll x, ll y){       // 解密,转换成密码
        string tmpans;
    
        for (ll i = x; i <= x + n - 1; i ++){
            for (ll j = y; j <= y + n - 1; j ++){
                if ((isPrime(num[i - x + 1][j - y + 1]) == isUpper(code[i][j])) && num[i - x + 1][j - y + 1] != 1 || (!num[i - x + 1][j - y + 1])) tmpans += code[i][j];
                else continue;
            }
        }
    
        ans += tmpans;
    }
    
    void restore(){                 // 转完后,把数字表还原
        for (ll i = 1; i <= n; i ++)
            for (ll j = 1; j <= n; j ++) num[i][j] = res[i][j];
    
        return;
    }
    
    int main(){
        ios::sync_with_stdio(0), cout.tie(0), cin.tie(0);
    
        cin >> n >> m;
    
        // 输入数字表
        for (ll i = 1; i <= n; i ++) 
            for (ll j = 1; j <= n; j ++){
                char x;
                cin >> x;
                num[i][j] = x - '0', res[i][j] = num[i][j];
            }
    
        // 输入字母表
        for (ll i = 1; i <= m; i ++) 
            for (ll j = 1; j <= m; j ++){
                cin >> code[i][j];
                if (code[i][j] >= 'A' && code[i][j] <= 'Z') dui[i][j] = code[i][j] - 'A' + 1;
                else dui[i][j] = code[i][j] - 'a' + 1;
            }
    
        // 枚举有效区域
        for (ll i = 1; i <= m - n + 1; i ++)    
            for (ll j = 1; j <= m - n + 1; j ++){
                if (isCorre(i, j)){
                    ll uppercnt = countUpper(i, j);
                    do{         // 根据题目要求解密
                        decode(i, j);
                        turnRight(1);
                    }while (uppercnt --);
    
                    restore();  // 解密完后把数字表回去
                }
            }
    
    
        // 输出答案
        if (!ans.size()) cout << "No solution";
        else cout << ans << endl;
    
        return 0;
    }
    

    结合注释可以更好地理解一下,Goodbye. Goodbye.

    • @ 2024-8-1 18:59:14

      你是不知道呀,前天孙涛给你改H1040的代码改得哭爹喊娘的,跟王老师抱怨了一下午

    • @ 2024-8-1 21:27:03

      他说2点之前给我改完,但是4点才好()只能说孙涛辛苦力(

    • @ 2024-9-15 12:10:05

      怎么用不了啊???

信息

ID
768
时间
1000ms
内存
256MiB
难度
8
标签
递交数
70
已通过
13
上传者