【csp模拟赛2】 爆搜 方格加数

匆匆过客 提交于 2019-12-17 05:50:32

 

【题目描述】

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\n",ans);
	fclose(stdin);fclose(stdout);
	return 0;
}

  

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!