【题目描述】
xyz1048576正在玩一个关于矩阵的游戏。
一个n*m的矩阵,矩阵中每个数都是[1,12]内的整数。你可以执行下列两个操作任意多次:
(1)指定一行,将该行所有数字+1。
(2)指定一列,将该列所有数字+1。
(3)如果执行完上述操作之后,矩阵中某个数变成了3,6,9,12其中的某一个,我们认为这个数是稳的。
给定初始矩阵,求出任意执行操作之后稳数的最多个数。
【输入格式】
第一行包含两个正整数n,m。
接下来n行,每行m个数,描述这个矩阵。
【输出格式】
一个整数,表示答案。
【输入样例1】
3 3
1 2 3
3 2 4
1 2 1
【输出样例1】
7
【输入样例2】
5 5
2 4 6 8 10
1 2 3 4 5
3 4 5 6 7
7 8 9 10 11
5 10 12 3 7
【输出样例2】
20
【数据规模及约定】
对于10%的数据,n,m≤2。
对于20%的数据,n,m≤5。
对于100%的数据,n,m≤10。
思路:
dfs,爆搜,先只考虑每一行,因为对于一行或者一列,加三次和加六次相对关系不变,我们可以对于每一行或列,枚举加0次,加一次,加两次的情况,DFS行后,循环处理列的情况,
每一列取和3取模相同的最大集合,统计答案。
代码:
#include"iostream" #include"cstdio" #include"cstdlib" using namespace std; const int N = 100; int n,m,ans,mod[5],a[N][N]; void check() { int sum=0; for(int j=1;j<=m;j++) { mod[0]=mod[1]=mod[2]=0; for(int i=1;i<=n;i++)if(a[i][j]<=12)mod[a[i][j]%3] ++ ; sum+=max(max(mod[0],mod[1]),mod[2]); } ans=max(ans,sum); } void dfs(int x) { if(x==n+1) { check(); return; } for(int i=0;i<=2;i++) { for(int j=1;j<=m;j++)a[x][j]+=i; dfs(x+1); for(int j=1;j<=m;j++)a[x][j]-=i; } } int main() { #ifdef yilnr #else freopen("zxx.in","r",stdin); freopen("zxx.out","w",stdout); #endif scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%d",&a[i][j]); } dfs(1); printf("%d ",ans); fclose(stdin);fclose(stdout); return 0; }