Codeforces Round #675 (Div. 2) B. Nice Matrix(思维+模拟)
题意:给你一个n × m n\times mn×m的矩阵,你可以对其中的任意元素进行自增或自减1 11操作。问你至少要经过多少次操作才能使得它变成nice矩阵?
nice矩阵的定义为:任一行或任一列都是回文序列。
思路:首先可以观察到,假设某个元素的位置是a[i][j],那么受它影响的元素的位置是
a[ n-i+1 ] [ j ] a[ n-i+1 ] [ m-j+1] a[ i ] [ m-j+1].
也就是每次选取一个元素a[ i ][ j ](i>=1&&i<=n/2,j>=1&&j<=m/2),然后找到这个数对应的三个数,通过+1或者-1让他们变成同一个数,且操作次数要最小。将这四个数从放进一个b数组,小到大进行排序,
p1=b[ 3 ]-b[ 0 ], p2=b[ 2 ]-b[ 1 ],p1+p2 就是操作的最小次数。
最后还要分一下奇偶就行了(奇数行或者列的时候要把这一行或者这一列单独计算,具体看代码)。
ps: (代码看着挺长的,其实只要写出来n,m都是奇数的情况,其实的根据这个稍微修改就行了。。。。。)
#include<iostream> #include<algorithm> typedef long long ll; using namespace std; int main() { int t; cin>>t; while(t--){ int a[105][105]; int n,m; cin>>n>>m; for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++) cin>>a[i][j]; } ll sum=0; int b[4]; if(n%2==1&&m%2==1) { for(int i=1;i<=n/2;i++){ for(int j=1;j<=m/2;j++){ b[0]=a[i][j]; int k=n-i+1; b[1]=a[k][j]; int tp=k; k=m-j+1; b[2]=a[tp][k]; b[3]=a[i][k]; sort(b,b+4); int p1=b[3]-b[0]; int p2=b[2]-b[1]; sum+=p1+p2; } } int tp1=n/2+1; int tp2=m/2+1; for(int i=1;i<=tp2;i++){ int k=m-i+1; int s=a[tp1][k]-a[tp1][i]; sum+=s; } for(int i=1;i<=tp1;i++){ int k=n-i+1; int s=abs(a[k][tp2]-a[i][tp2]); sum+=s; } cout<<sum<<endl; } else if(n%2==0&&m%2==0){ for(int i=1;i<=n/2;i++){ for(int j=1;j<=m/2;j++){ b[0]=a[i][j]; int k=n-i+1; b[1]=a[k][j]; int tp=k; k=m-j+1; b[2]=a[tp][k]; b[3]=a[i][k]; sort(b,b+4); int p1=b[3]-b[0]; int p2=b[2]-b[1]; sum+=p1+p2; } } cout<<sum<<endl; } else if(n%2==1&&m%2==0) { for(int i=1;i<=n/2;i++){ for(int j=1;j<=m/2;j++){ b[0]=a[i][j]; int k=n-i+1; b[1]=a[k][j]; int tp=k; k=m-j+1; b[2]=a[tp][k]; b[3]=a[i][k]; sort(b,b+4); int p1=b[3]-b[0]; int p2=b[2]-b[1]; sum+=p1+p2; } } int tp1=n/2+1; int tp2=m/2; for(int i=1;i<=tp2;i++){ int k=m-i+1; int s=abs(a[tp1][k]-a[tp1][i]); sum+=s; } cout<<sum<<endl; } else if(n%2==0&&m%2==1){ for(int i=1;i<=n/2;i++){ for(int j=1;j<=m/2;j++){ b[0]=a[i][j]; int k=n-i+1; b[1]=a[k][j]; int tp=k; k=m-j+1; b[2]=a[tp][k]; b[3]=a[i][k]; sort(b,b+4); int p1=b[3]-b[0]; int p2=b[2]-b[1]; sum+=p1+p2; } } int tp1=n/2; int tp2=m/2+1; for(int i=1;i<=tp1;i++){ int k=n-i+1; int s=abs(a[k][tp2]-a[i][tp2]); sum+=s; } cout<<sum<<endl; } } } /* 5 4 5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 5 5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 */