CF991D Bishwock

CF991D Bishwock

题目描述

给一个\(2\times n\)的网格,上面一些位置以及被覆盖上了。现在你有一种形状为L的小块,每个由三个小格组成,构成L型
现在问你,当前的网格最多还能摆多少小块(不能覆盖以及覆盖过的格子)

输入格式

两行两个字符串由\(X,0\)组成,\(X\)表示被覆盖了,\(0\)表示还没有

输出格式

一行 一个整数

样例输入

00X00X0XXX0
0XXX0X00X00

样例输出

4

对于\(100\)%的数据满足\(n\le 10^5\)

题目分析

​ 大约一年前的模拟赛上似乎就出过这道题。(考试后证明我是对的......) 至于为什么要更这篇题解,因为今年差点没切(去年都切了.... 其实最后今年也没切,数组开小了)

​ 个人想法就不说了,乱七八糟想了一堆,一个没搞出来。周围大佬们都切了,就先去看T2了(事实证明是正确的,如果T1切掉也就不会那么认真的去考虑T2)。

​ 闲话少叙,步入正题。

​ 首先我们观察一下数据范围....(然鹅并没有什么用) 突破口是在\(2\times n\)的矩阵,以及只有一种L型的块块。 所以,对于一个\(2\times 2\)的矩阵,合法情况是一定的。具体几种长什么样可以手画一下。

​ 所以我们想到一种类似递推的更新方式。 预处理出来每列的状态:

\(f[i][1/2/3/4]\)分别表示每列的一种可能更新的状态。

\(f[i][1]\) \(XX\) \(f[i][2]\) \(0X\) \(f[i][3]\)$ X0 $ \(f[i][4]\) \(00\)

\(f[i][0]\)用来记录当前列的答案。

​ 然后就是一堆特判。 注意对于每列更新完之后,\(f[i][2/3]\)这两种情况需要清零,而\(f[i-1][4]=1\)\(f[i][4]=1\)时,\(f[i][4]\)只会被用到一次,所以可以拆成\(f[i][2/3] = 1\)以便接下来的操作。具体实现见代码。

​ code:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100020;
int f[N][5];
char str[3][N];
int main()
{
	// freopen("a.in", "r", stdin);
	// freopen("a.out", "w", stdout);
	scanf("%s", str[1] + 1);
	scanf("%s", str[2] + 1);
	int n = strlen(str[1] + 1);
	memset(f, -1, sizeof f);
	for(int i = 1 ; i <= n ; i ++)
		f[i][0] = 0;
	for(int j = 1 ; j <= n ; j ++)
	{
		if(str[1][j] == '0' && str[2][j] == '0')
			f[j][4] = 1;
		else
			if(str[1][j] == '0' && str[2][j] == 'X')
				f[j][3] = 1;
		else
			if(str[1][j] == 'X' && str[2][j] == '0')
				f[j][2] = 1;
		else
			if(str[1][j] == 'X' && str[2][j] == 'X')
				f[j][1] = 1;
	}
	for(int i = 2 ; i <= n ; i ++)
	{
		if(f[i - 1][4] == 1 && f[i][4] == 1)
		{
			f[i][0] ++;
			f[i][2] = 1;
			f[i][3] = 1;
			f[i][4] = 0;
		}
		else
			if(f[i - 1][2] == 1 && f[i][4] == 1)
			{
				f[i][0] ++;
				f[i][4] = 0;
			}
		else
			if(f[i - 1][3] == 1 && f[i][4] == 1)
			{
				f[i][0] ++;
				f[i][4] = 0;
			}
		else
			if(f[i - 1][4] == 1 && f[i][3] == 1)
			{
				f[i][0] ++;
				f[i][3] = 0;
			}
		else
			if(f[i - 1][4] == 1 && f[i][2] == 1)
			{
				f[i][0] ++;
				f[i][2] = 0;
			}
	}
	int ans = 0;
	for(int i = 1 ; i <= n ; i ++)
		ans += f[i][0];
	printf("%d", ans);
	fclose(stdin);
	fclose(stdout);
	return 0;
}

posted @ 2019-10-24 15:58  sky20030724  阅读(174)  评论(0编辑  收藏  举报