0922考试T1
0922考试T1
题目描述:
xyz1048576正在玩一个关于矩阵的游戏。一个n*m的矩阵,矩阵中每个数都是[1,12]内的整数。你可以执行下列两个操作任意多次:
(1)指定一行,将该行所有数字+1。
(2)指定一列,将该列所有数字+1。
(3)如果执行完上述操作之后,矩阵中某个数变成了3,6,9,12其中的某一个,我们认为这个数是稳的。
给定初始矩阵,求出任意执行操作之后稳数的最多个数。
\(n, m <= 10\)
应该算是乱搞把。
我们可以知道,对任意某一行或某一列,操作一次或两次是优的,再多就不优了。因为操作三次,相当于没有变化,操作四次相当于操作一次,操作五次相当于操作两次……
我们可以枚举行的状态,用三进制枚举,第\(i - 1\)位为0/1/2表示第\(i\)行不操作/操作一次/操作两次。
行的次数确定了,我们在找每一列\(3, 6, 9, 12\),\(2, 5, 8, 11\),\(1,4,7,10\)的个数,取最大值统计答案就好了。
#include <bits/stdc++.h>
using namespace std;
inline long long read() {
long long s = 0, f = 1; char ch;
while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
return s * f;
}
const int N = 11;
int n, m, ans;
int a[N][N], tmp[N][N], lie[N][3], b[N];
int calc(int x) {
int cntx = 0;
while(x) {
b[++cntx] = x % 3; x /= 3;
}
int res = 0;
for(int i = 1;i <= n; i++)
for(int j = 1;j <= m; j++) tmp[i][j] = a[i][j];
for(int i = 1;i <= n; i++)
for(int j = 1;j <= m; j++) tmp[i][j] += b[i];
for(int i = 1;i <= m; i++) lie[i][0] = lie[i][1] = lie[i][2] = 0;
for(int j = 1;j <= m; j++) {
for(int i = 1;i <= n; i++) {
if(tmp[i][j] == 3 || tmp[i][j] == 6 || tmp[i][j] == 9 || tmp[i][j] == 12) lie[j][0] ++;
if(tmp[i][j] == 2 || tmp[i][j] == 5 || tmp[i][j] == 8 || tmp[i][j] == 11) lie[j][1] ++;
if(tmp[i][j] == 1 || tmp[i][j] == 4 || tmp[i][j] == 7 || tmp[i][j] == 10) lie[j][2] ++;
}
res += max(max(lie[j][0], lie[j][1]), lie[j][2]);
}
return res;
}
int main() {
n = read(); m = read();
for(int i = 1;i <= n; i++)
for(int j = 1;j <= m; j++) a[i][j] = read();
int nx = pow(3, n);
for(int i = 0;i <= nx - 1; i++)
ans = max(ans, calc(i));
printf("%d\n", ans);
fclose(stdin); fclose(stdout);
return 0;
}