51NOD 1316 回文矩阵 【枚举】

1316 回文矩阵
题目来源: TopCoder
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏  关注
 一个N*M的矩阵A完全由01两个数字组成(08),矩阵第i行第j列上的项为A[i][j],i与j从0标起,即0<=i0<=j1)将矩阵中的任一项A[i][j]改为数字1;
(2)将矩阵中的任一项A[i][j]改为数字0;
现在给出初始的矩阵A,要求经过最少次操作,使矩阵A中至少有RowCount行是回文的,同时存在至少ColumCount列是回文的。输出这个最少操作的次数。
矩阵中第r行是回文的,指序列{A[r][0],A[r][1],...A[r][M-1]}回文,即所有的 i 有A[r][i]=A[r][M-1-i];
矩阵中第c列是回文的,指序列{A[0][c],A[1][c],...A[N-1][c]}回文,即所有的 i 有A[i][c]=A[N-1-i][c].

例如4x4的矩阵如下:
0000
1000
1100
1110
要求RowCount = 2,且ColumCount = 2.
可以将A[3][0]改为0,使第0行与第3行回文,同时第0列与第3列回文。变化后如下:
0000
1000
1100
0110
Input
第一行两个正整数,表示RowCount,ColumCount,且0<=RowCount<=N,0<=ColumCount<=M.
第二行一个整数N,即矩阵的行数,1<=N<=8.
之后有N行,每行一个由M个‘0’、‘1’字符构成的字符串,表示N*M矩阵的信息。
Output
一个整数,表示最少操作的次数。
Input示例
2 2
4
0000
1000
1100
1110
Output示例
1
孔炤 (题目提供者)

枚举出是回文的r行和c列
确定A[i][j],如果i行是回文 A[i][m-j-1]=A[i][j]
j列是回文 A[n-i-1][j]=A[i][j]
n-i-1行是回文 A[n-i-1][m-j-1]=A[i][j]…

遍历i,j 选出A[i][j]能确定的位置,并确定最小需要多少次改变操作即可

O(CrnCcmnm)

#include
#include 

#define ll long long
#define pii pair
#define MEM(a,x) memset(a,x,sizeof(a))

using namespace std;

const int inf=1e9+7;

char str[8][9];
bool vis[8][8];

int n,m;
vectorvec;

inline int bits(int x){//x含有多少个1
    int ans=0;
    while(x){
        ans+=(x&1);
        x>>=1;
    }
    return ans;
}

int f(int i,int j,int x,int y){//a[i][j]能确定的位置,至少多少次操作使得他们值全部一样
    vec.clear();
    vec.push_back({i,j});
    int ii=n-i-1,jj=m-j-1;
    bool flag=false;
    if((1<if((1<true;
        }
    }
    if((1<if(!flag){
            if((1<int ans=inf;
    for(char k='0';k<='1';++k){
        int sum=0;
        for(int z=0;zint i=vec[z].first,j=vec[z].second;
            sum+=abs(k-str[i][j]);
        }
        ans=min(ans,sum);
    }
    for(int z=0;zint i=vec[z].first,j=vec[z].second;
        vis[i][j]=true;
    }
    return ans;
}

int check(int x,int y){
    MEM(vis,0);
    int ans=0;
    for(int i=0;ifor(int j=0;jif(vis[i][j]){
                continue;
            }
            ans+=f(i,j,x,y);
        }
    }
    return ans;
}

int slove(int r,int c){
    int ans=64;
    for(int i=0,endI=(1<if(bits(i)==r){
            for(int j=0,endJ=(1<if(bits(j)==c){
                    ans=min(ans,check(i,j));
                }
            }
        }
    }
    return ans;
}

int main()
{
    //freopen("/home/lu/code/r.txt","r",stdin);
    int r,c;
    while(~scanf("%d%d",&r,&c)){
        scanf("%d",&n);
        for(int i=0;iscanf("%s",str[i]);
        }
        m=strlen(str[0]);
        printf("%d\n",slove(r,c));
    }
    return 0;
}

你可能感兴趣的:(51NOD)