题目大意

给定一个 列的棋盘,每个格子里有一个字符,红色()或白色()。你一开始要选择一个红色格子,每一步可以往上、下、左、右四个方向走,过程中到达的格子必须是红色的,每个格子只能经过一遍(这里指的经过一遍是严格意义上的,后面的移动过程中不能途经这个格子)。问你最多能走多少步,简而言之就是最长一笔画。特殊的,如果没有红色格子,答案为

前置知识

签到题,线性枚举即可,考虑到细节较多(队里一位场切紫题的大佬没调出来),评

解法

  • 发现只有 行,所以可以将棋盘分为 列,有四种情况(型号 ):
  • 如果相邻两列情况相同,就直接合并,所以最后会分成 个块,每个块有个 ,指包含多少列,相邻两个块型号不同。

  • 考虑从左到右扫 ,记录两个变量 ,前者指通过当前块后的格子最大值(注意,这里两个变量都是格子数,最后减个 就是答案),后者是全局最大值。

  • 两个白色格子()直接清空 ,一红一白的情况也随便做,这里着重描述一下两个红,左右两边夹着两个一红一白()的情况。

  • 如果前后两个一红一白的块,一个是 ,另一个是 (即型号不同),如果当前块的长度是偶数,说明当前块的格子可以全部走完, 直接加上;奇数,如果想要通过下一个快,那么最少最少要不能经过一个格子,不过下一个块还有一个格子,不亏,直接加。如果前后两个块型号相同,那么就是前面一种情况反过来,偶数减 奇数全加上。

  • 然后就做完了,不过坑点比较多,对于一些人的代码别忘了把第 个块和 第 + 个块型号设为 (表示不存在),否则会出现错误。时间复杂度 ,与输入同阶,足以通过此题。

code

最后放上代码:

using namespace std;
const int NR = 1e6 + 1;
int n;
char mp[2][NR];
struct Node{
	int type, len;
}a[NR];
int cnt, maxn = 0;
int gettype(int i){
	if (mp[0][i] == 'R' && mp[1][i] == 'R') return 0;
	if (mp[0][i] == 'W' && mp[1][i] == 'W') return 1;
	if (mp[0][i] == 'R' && mp[1][i] == 'W') return 2;
	return 3;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);
	cin >> n;
	for (int i = 0; i <= 1; i++)
		for (int j = 1; j <= n; j++)
			cin >> mp[i][j];
	a[++cnt] = (Node){gettype(1), 1};
	for (int i = 2; i <= n; i++){
		int t = gettype(i);
		if (t == a[cnt].type) a[cnt].len++;
		else a[++cnt] = (Node){t, 1};
	}
	a[0] = (Node){-1, -1};
	a[cnt + 1] = (Node){-1, -1};
	int ans = 0;
	for (int i = 1; i <= cnt; i++){
		int len = a[i].len;
		if (a[i].type == 0){
			maxn = max(maxn, ans + len * 2);
			if (len % 2 == 0){
				if (a[i - 1].type == 1) ans += len * 2;
				else if (a[i - 1].type == 2){
					if (a[i + 1].type == 1) ans += len * 2;
					else if (a[i + 1].type == 2) ans += len * 2;
					else if (a[i + 1].type == 3) ans += len * 2 - 1;
					else ans += len * 2;
				}
				else if (a[i - 1].type == 3){
					if (a[i + 1].type == 1) ans += len * 2;
					else if (a[i + 1].type == 2) ans += len * 2 - 1;
					else if (a[i + 1].type == 3) ans += len * 2;
					else ans += len * 2;
				}
				else ans += len * 2;
			}
			else{
				if (a[i - 1].type == 1) ans += len * 2;
				else if (a[i - 1].type == 2){
					if (a[i + 1].type == 1) ans += len * 2;
					else if (a[i + 1].type == 2) ans += len * 2 - 1;
					else if (a[i + 1].type == 3) ans += len * 2;
					else ans += len * 2;
				}
				else if (a[i - 1].type == 3){
					if (a[i + 1].type == 1) ans += len * 2;
					else if (a[i + 1].type == 2) ans += len * 2;
					else if (a[i + 1].type == 3) ans += len * 2 - 1;
					else ans += len * 2;
				}
				else ans += len * 2;
			}
		}
		else if (a[i].type == 1){
			ans = 0;
		}
		else if (a[i].type == 2){
			if (a[i - 1].type == 0){
				ans += len;
				maxn = max(maxn, ans);
			}
			else if (a[i - 1].type == 1){
				ans = len;
				maxn = max(maxn, ans);
			}
			else if (a[i - 1].type == 3){
				ans = len;
				maxn = max(maxn, ans);
			}
			else{
				ans += len;
				maxn = max(maxn, ans);
			}
		}
		else if (a[i].type == 3){
			if (a[i - 1].type == 0){
				ans += len;
				maxn = max(maxn, ans);
			}
			else if (a[i - 1].type == 1){
				ans += len;
				maxn = max(maxn, ans);
			}
			else if (a[i - 1].type == 2){
				ans = len;
				maxn = max(maxn, ans);
			}
			else{
				ans += len;
				maxn = max(maxn, ans);
			}
		}
	}
	if (maxn > 0) maxn--;
	cout << maxn << endl;
	return 0;
}

THE END