杭电多校十 1009-Painting Game(思维+贪心)

140 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

题目链接:杭电多校10 - Virtual Judge

image.png 样例输入:

4
3 Alice
3 Bob
19 Alice
23 Bob

样例输出:

1
2
8
10

题意:给你一个1*n的表格,我们可以在每一个小格里面涂黑,但是要保证不能有相邻的两个小格均被涂黑,Alice和Bob两个玩家轮流操作,Alice希望让涂黑的小格的数目尽量小,而Bob希望让涂黑的小格数目尽量多,问在两个人都采取最佳操作的前提下最后会有多少个小格被涂黑?

每组输入先给出一个n,再给出先手

分析:其实这道题只要我们好好模拟一下就能够猜出结论,就是对于Alice来说为了使得空白的小方格尽量多,那么就会选择每次左边空出一个小方格使其由能选变为不能选,这是什么意思呢?就比如一开始有n个小方格,Alice肯定先涂黑第二个小方格,这样第一个小方格就永远不会被选了,那假如第一个小方格被涂黑了,那么Alice会涂第几个小方格呢?答案是第四个,为什么不是第三个呢?第三个左边不是空出来了一个未涂黑的小方格吗?其实第三个左边的小方格本身就不会被涂黑,而我们如果涂黑第四个小方格,那么第三个小方格也会因为我们的操作而变得不能涂黑,所以Alice就是按照这个最优策略来进行涂色的。

下面再看一下Bob,假如我们一开始有一个1*n的格子,均未被涂色,那么Bob第一次肯定选择第三个小格子涂色,因为这样第一个小格子最后一定会有人涂黑,这样就不会有小方格浪费,而Bob就是要尽量使得被浪费的小方格尽量少,如果第一个小方格被涂黑了,那么Bob就选择第五个小方格涂黑,这样中间会剩余三个小方格未被染色,这样其中有一个小方格最后一定会被染色,这样就能使得被浪费的小方格尽量小。

通过这样模拟发现染色方案的循环节是7,每7个格子就会有3个格子被染色,所以我们只需要研究n<7的情况即可,这个比较简单,只需要模拟一下就可以了,在这我就不赘述了。

细节见代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
char s[10];
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		scanf("%d%s",&n,s);
		int ans;
		if(s[0]=='B')
		{
			ans=n/7*3;
			if(n%7==0) ;
			else if(n%7<=2) ans++;
			else if(n%7<=4) ans+=2;
			else ans+=3;
		}
		else
		{
			ans=n/7*3;
			if(n%7==0) ;
			else if(n%7<=3) ans++;
			else if(n%7<=5) ans+=2;
			else ans+=3;
		}
		printf("%d\n",ans);
	}
	return 0;
}