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;
}
posted @ 2020-09-23 22:00  C锥  阅读(128)  评论(0编辑  收藏  举报