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

*/
View Code

 

posted @ 2020-10-05 21:05  Swelsh-corgi  阅读(209)  评论(0编辑  收藏  举报