题目描述
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 }