LightOJ 1363 - Binary Matrix (II)

题意:给定一个矩阵,可以相邻的行或列交换一个元素。首尾也算相邻。最小交换多少次。可以使每行梅列的1的个数相同。或每一行的1的数量一样多。或每一列一样多。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
const int N = 1009;
const int INF = 0x3f3f3f3f;
char a[N][N];
int row[N],col[N],re[N];
int n,m,s;
int get(int nn,int f,int t)
{
    int l=f,k=0;
    int ret = 0;
    while(k<nn)
    {
        if(re[l]==t)
        {

        }else if(re[l]>t)
        {
            ret+=re[l]-t;
            re[(l+1)%nn] += re[l]-t;
        }else
        {
            ret+=t-re[l];
            re[(l+1)%nn] -= t-re[l];
        }
        l=(l+1)%nn;
        k++;
    }
    return ret;
}
void solve()
{
    int k = 0,ans = 0;
    if(s%n==0)
    {
        k|=1;
        int tmp = INF;
        for(int i=0;i<n;i++)
        memcpy(re,row,sizeof(row)),tmp = min(tmp,get(n,i,s/n));
        ans +=tmp;
       // cout<<tmp<<" - ";
    }
    //cout<<k<<endl;
    if(s%m==0)
    {
        k|=2;
        int tmp = INF;
        for(int i=0;i<m;i++)
        memcpy(re,col,sizeof(col)),tmp = min(tmp,get(m,i,s/m));
        ans+=tmp;
        //cout<<tmp<<endl;
    }
    //cout<<"K= "<<k<<endl;
    if(k==3)
    printf("both %d\n",ans);
    else if(k==1)
    printf("row %d\n",ans);
    else if(k==2)
    printf("column %d\n",ans);
    else printf("impossible\n");
}
int main()
{
    freopen("in.txt","r",stdin);
    int cas,T= 1;
    scanf("%d",&cas);
    while(cas--)
    {
        memset(row,0,sizeof(row));
        memset(col,0,sizeof(col));s=0;
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
        {
            scanf("%s",a[i]);
            for(int j=0;j<m;j++)
            if(a[i][j]=='1')
            row[i]++,col[j]++,s++;
        }
        printf("Case %d: ",T++);
        solve();
    }
    return 0;
}


你可能感兴趣的:(LightOJ 1363 - Binary Matrix (II))