CF 1980E Permutation of Rows and Columns(*1600) 思维

CF 1980E Permutation of Rows and Columns(*1600) 思维

题目链接

题意

给你两个大小为 \(n*m\) 的矩阵,其中元素的是 \(n*m\) 的排列,你可以任意交换两行或者任意交换两列。

求是否通过操作使得矩阵 \(a\) 变成矩阵 \(b\)

思路

由于矩阵中的元素是排列,并且我们每次只能交换两行或者两列。容易发现无论怎么交换同一行和同一列中的元素种类是不会改变的,只会改变相对位置。那么我们可以记录下矩阵 \(a\) 中每个元素所在的行和列的位置,再按照其在矩阵 \(b\) 矩阵的位置进行交换,交换完所有位置后,如果 \(a\)\(b\) 一致,那么输出 "Yes", 否则一定无法通过交换操作使得 矩阵 \(a\) 变成矩阵 \(b\) 。输出 “No”。

代码

void Showball(){
   int n,m;
   cin>>n>>m;
   vector<vector<int>> a(n,vector<int>(m)),b(n,vector<int>(m));
   vector<int> row(n*m),col(n*m);
 
   for(int i=0;i<n;i++){
      for(int j=0;j<m;j++){
         cin>>a[i][j];
         a[i][j]--;
         row[a[i][j]]=i;
         col[a[i][j]]=j;
      }
   }
 
   for(int i=0;i<n;i++){
      for(int j=0;j<m;j++){
         cin>>b[i][j];
         b[i][j]--;
      }
   }
 
   for(int i=0;i<n;i++){
      int r=row[b[i][0]];
      swap(a[i],a[r]);
      for(int j=0;j<m;j++){
         row[a[i][j]]=i;
         row[a[r][j]]=r;
      }
   }
 
   for(int j=0;j<m;j++){
      int c=col[b[0][j]];
      for(int i=0;i<n;i++){
         swap(a[i][j],a[i][c]);
         col[a[i][j]]=j;
         col[a[i][c]]=c;
      }
   }
 
   cout<<(a==b?"YES\n":"NO\n");
}
posted @ 2024-06-15 22:22  Showball  阅读(14)  评论(0编辑  收藏  举报