CF991D Bishwock

CF991D Bishwock

洛谷评测传送门

题目描述

Bishwock is a chess figure that consists of three squares resembling an "L-bar". This figure can be rotated by 90, 180 and 270 degrees so it can have four possible states:

<br></br>XX XX .X X.<br></br>X. .X XX XX<br></br>Bishwocks don't attack any squares and can even occupy on the adjacent squares as long as they don't occupy the same square.

Vasya has a board with 2\times n2×n squares onto which he wants to put some bishwocks. To his dismay, several squares on this board are already occupied by pawns and Vasya can't put bishwocks there. However, pawns also don't attack bishwocks and they can occupy adjacent squares peacefully.

Knowing the positions of pawns on the board, help Vasya to determine the maximum amount of bishwocks he can put onto the board so that they wouldn't occupy the same squares and wouldn't occupy squares with pawns.

输入格式

The input contains two nonempty strings that describe Vasya's board. Those strings contain only symbols "0" (zero) that denote the empty squares and symbols "X" (uppercase English letter) that denote the squares occupied by pawns. Strings are nonempty and are of the same length that does not exceed 100100 .

输出格式

Output a single integer — the maximum amount of bishwocks that can be placed onto the given board.

题意翻译

Bishwock是一种特殊的棋,它的放置规则如下所示(X代表棋,类似于俄罗斯方块可以旋转)

题目

给出一个2n2∗n*的初始局面,问最多能放多少个棋(X代表此处不能放,0代表此处可以放)

感谢@attack 提供翻译

输入输出样例

输入 #1复制

输出 #1复制

输入 #2复制

输出 #2复制

输入 #3复制

输出 #3复制

输入 #4复制

输出 #4复制

题解:

2019.10.24模拟赛各种假做法后来模拟AC场

模拟:

我们发现,所有的情况无外乎这么几种:

第一种:连着三列都是0,当且仅当这时,能一次性放进去两个直角形。

000
000

第二种:

?0  00
00  ?0

(双0在右侧)

第三种:

00  0?
0?  00

(双零在左侧)

依照题意模拟就行了

AC模拟代码:

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e5+10;
bool v[5][maxn];
char s[5][maxn];
int ans,len;
int main()
{
	scanf("%s%s",s[1]+1,s[2]+1);
	memset(v,1,sizeof(v));
	len=strlen(s[1]+1);
	for(int i=1;i<=2;i++)
		for(int j=1;j<=len;j++)
			if(s[i][j]=='0')
				v[i][j]=0;
	for(int i=1;i<=len;i++)
	{
		if(!v[1][i]&&!v[2][i]&&!v[1][i+1]&&!v[2][i+1]&&!v[1][i+2]&&!v[2][i+2])//000
		{                                                                     //000
			v[1][i]=v[2][i]=v[1][i+1]=v[2][i+1]=v[1][i+2]=v[2][i+2]=1;
			i+=2;
			ans+=2;
			continue;
		}
		else if((!v[1][i+1]&&!v[2][i+1])&&(!v[1][i]||!v[2][i]))
	    {
			v[1][i+1]=v[2][i+1]=1;
			if(!v[1][i])
			{
				v[1][i]=1;
				i++,ans++;
				continue;
			}
			else
			{
				v[2][i]=1;
				i++,ans++;
				continue;
			}
			continue;
		}
		else if((!v[1][i]&&!v[2][i])&&(!v[1][i+1]||!v[2][i+1]))
		{
			v[1][i]=v[2][i]=1;
			if(!v[1][i+1])
			{
				v[1][i+1]=1;
				i++,ans++;
				continue;
			}
			else
			{
				v[2][i+1]=1;
				i++,ans++;
				continue;
			}
			continue;
		}
	}
	printf("%d",ans);
	return 0;
}

后来,本蒟蒻知道了还可以贪心

玩过俄罗斯方块的都知道,如果落下来很多直角形的块块,(其实不只是直角形),那么肯定要让它尽量地把下面填满(不留空隙),这样得到的答案才是最优的。

那么我们分析一下:如果全是空的话,就一正一反地放就成了。

如果不全是空的话,即会有X分割,那么会有完全分割和不完全分割两种情况。

完全分割:(让人一看就很舒坦)

00X0XX
0XX00X

不完全分割:

XX00XX
X0000X

如果如果碰到了一种情况:(这里只是举局部例子)

X0X
000

那么我们将会面临着一个艰难的抉择:往左边放,还是往右边放?

根据刚刚的“俄罗斯方块原理”,如果往右边放的话,肯定会占用其它的空间,使得其不能再放一个合法的直角。所以我们碰到这种情况的时候,选左边的先放,这就是贪心策略。

posted @ 2019-10-24 16:12  Seaway-Fu  阅读(202)  评论(0编辑  收藏  举报