P3492 题解

题意:

\(n\)\(m\) 列的矩阵,只能交换两行或交换两列,问能否从一个矩阵变成另一个。

分析:

交换两行,这两行内部不会有数字改变;交换两列,只会改变一行内的数字顺序,列同理。可以得出:交换之后原本一行和一列的数字是不会改变的。

所以判断结果矩阵的每行和每列是否和原矩阵的内容相等。如果不等是不可能的;如果相等,发现问题中的行和列是相互约束的,所以一定成立。

所以只用判断这些就可以了,按理说该用哈希的。但是他既然保证了元素不重而且是真的啥都不卡,我用了 \(map\)(乐)。

代码是易于理解的:

#include<bits/stdc++.h>
using namespace std;
int t, n, m, a[10010][10010];
map <map<int, bool>, int> sx, sy, tx, ty; //纯偷懒(乐子人)
int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);std::cout.tie(0);
    cin >> t; while(t--){
        cin >> n >> m; sx.clear(), sy.clear(), tx.clear(), ty.clear();
        for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) cin >> a[i][j];
        for(int i = 1; i <= n; i++){ map<int, bool>mp; mp.clear();
            for(int j = 1; j <= m; j++) mp[a[i][j]] = 1; sx[mp]++;}
        for(int j = 1; j <= m; j++){ map<int, bool>mp; mp.clear();
            for(int i = 1; i <= n; i++) mp[a[i][j]] = 1; sy[mp]++;}
        for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) cin >> a[i][j];
        for(int i = 1; i <= n; i++){ map<int, bool>mp; mp.clear();
            for(int j = 1; j <= m; j++) mp[a[i][j]] = 1; tx[mp]++;}
        for(int j = 1; j <= m; j++){ map<int, bool>mp; mp.clear();
            for(int i = 1; i <= n; i++) mp[a[i][j]] = 1; ty[mp]++;}
        cout << (sx==tx&&sy==ty?"TAK\n":"NIE\n"); //map是有内置判断等于的
    }
}
posted @ 2023-11-01 16:53  xlpg0713  阅读(30)  评论(0)    收藏  举报