Fork me on GitHub

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

 

【题目描述】

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;
}

  

posted @ 2019-09-17 20:33  yelir  阅读(224)  评论(0编辑  收藏  举报