【CodeForces】426D Sereja and Table

传送门

题目描述

Sereja has an n × m rectangular table a, each cell of the table contains a zero or a number one. Sereja wants his table to meet the following requirement: each connected component of the same values forms a rectangle with sides parallel to the sides of the table. Rectangles should be filled with cells, that is, if a component form a rectangle of size h × w, then the component must contain exactly hwcells.

A connected component of the same values is a set of cells of the table that meet the following conditions:

  • every two cells of the set have the same value;
  • the cells of the set form a connected region on the table (two cells are connected if they are adjacent in some row or some column of the table);
  • it is impossible to add any cell to the set unless we violate the two previous conditions.

Can Sereja change the values of at most k cells of the table so that the table met the described requirement? What minimum number of table cells should he change in this case?

解题思路

代码

(太丑勿喷qwq)

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 int n,m,k;
  7 int map[150][150],map1[150][150];
  8 int temp[150];
  9 int ff=99999999;
 10 inline void read(int &x){
 11     x=0; register char ch=getchar();
 12     while(ch<'0'||ch>'9')ch=getchar();
 13     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
 14 }
 15 inline int get(int x,int y){
 16     int tot=0;
 17     for(register int i=1;i<=m;i++){
 18         if(map[x][i]==map[y][i])tot++;
 19     }
 20     int left=m-tot;
 21     return min(left,tot);
 22 }
 23 inline int get1(int x){
 24     int tot=0;
 25     for(register int i=1;i<=m;i++){
 26         if(map[x][i]==temp[i])tot++;
 27     }
 28     int left=m-tot;
 29     return min(left,tot);
 30 }
 31 inline int gets(int x,int y){
 32     int tot=0;
 33     for(register int i=1;i<=m;i++){
 34         if(map1[x][i]==map1[y][i])tot++;
 35     }
 36     int left=m-tot;
 37     return min(left,tot);
 38 }
 39 inline int get1s(int x){
 40     int tot=0;
 41     for(register int i=1;i<=m;i++){
 42         if(map1[x][i]==temp[i])tot++;
 43     }
 44     int left=m-tot;
 45     return min(left,tot);
 46 }
 47 inline void ini(long long num){
 48     //cout<<num<<endl;
 49     int now=0;
 50     while(num){
 51         temp[++now]=num&1;
 52         //cout<<temp[now]<<' ';
 53         num=num>>1;
 54     }
 55     // for(register int i=1;i<=m;i++){
 56     //     cout<<temp[i]<<' ';
 57     // }
 58     // cout<<endl;
 59 }
 60 int main(){
 61     read(n),read(m),read(k);
 62     for(register int i=1;i<=n;i++){
 63         for(register int j=1;j<=m;j++){
 64             read(map[i][j]);
 65             map1[j][i]=map[i][j];
 66         }
 67     }
 68     if(k<n){
 69         register int ans=99999999;
 70         for(register int i=1;i<=n;i++){
 71             register int tot=0;
 72             for(register int j=1;j<=n;j++){
 73                 if(j!=i){
 74                     tot+=get(i,j);
 75                 }
 76             }
 77             ans=min(ans,tot);
 78         }
 79         if(ans<=k){
 80             cout<<ans<<endl;
 81             return 0;
 82         }
 83         cout<<-1<<endl;
 84         return 0;
 85     }
 86     else if(k>=m){
 87         register int ans=99999999;
 88         for(register int i=0;i<(1<<(m+1));i++){
 89             ini(i);
 90             register int tot=0;
 91             for(register int j=1;j<=n;j++){
 92                 tot+=get1(j);
 93             }
 94             ans=min(ans,tot);
 95         }
 96         if(ans<=k){
 97             cout<<ans<<endl;
 98             return 0;
 99         }
100         cout<<-1<<endl;
101         return 0;
102     }
103     swap(n,m);
104     if(k<n){
105         register int ans=99999999;
106         for(register int i=1;i<=n;i++){
107             register int tot=0;
108             for(register int j=1;j<=n;j++){
109                 if(j!=i){
110                     tot+=gets(i,j);
111                 }
112             }
113             ans=min(ans,tot);
114         }
115         if(ans<=k){
116             cout<<ans<<endl;
117             return 0;
118         }
119         cout<<-1<<endl;
120         return 0;
121     }
122     else if(k>=m){
123         register int ans=99999999;
124         for(register int i=0;i<(1<<(m+1));i++){
125             ini(i);
126             register int tot=0;
127             for(register int j=1;j<=n;j++){
128                 tot+=get1s(j);
129             }
130             ans=min(ans,tot);
131         }
132         if(ans<=k){
133             cout<<ans<<endl;
134             return 0;
135         }
136         cout<<-1<<endl;
137         return 0;
138     }
139 }

猜你喜欢

转载自www.cnblogs.com/Fang-Hao/p/9097507.html