首页 > 其他分享 >ARC_069 D - Menagerie 题解

ARC_069 D - Menagerie 题解

时间:2024-07-17 09:42:01浏览次数:10  
标签:nxt Menagerie 两位 069 题解 紧邻 int ans 身份

image

image

image

atcoder

一道很有意思的模拟题啊。

思路很重要。

首先,我们只要知道连续两只动物的身份,就可以根据 \(s\) 推出所有动物的身份。

不妨假设我们知道第一只和第二只动物的身份,一共有几种情况呢?

用 \(1\) 代表羊,\(0\) 代表狼。

那么,共有 \(2^2=4\) 种情况,分别为:

00 01 10 11

然后我们分别推出每个动物的身份,再判断是否合法即可。

接下来讲实现。

为了方便,用 \(pair\) 数组 \(nxt\) 记录该坐标紧邻的两个位置。

从第三个位置起,每个位置可根据前两位推出。

分类讨论一下:

\(1°\) 若前一位是羊,即 ans[i - 1] == 1

  • s[i - 1] == 'o',说明第 \(i - 1\) 位紧邻的两位身份相同,则 ans[i] == ans[i - 2]

  • 否则,紧邻的两位身份不同,则 ans[i] = 1 - ans[i - 2],以此即可。

\(2°\) 否则前一位是狼,即 ans[i - 1] == 0

  • s[i - 1] == 'x',狼说谎话,说明第 \(i - 1\) 位紧邻的两位身份相同,则 ans[i] == ans[i - 2]

  • 否则,身份不同,则 ans[i] = 1 - ans[i - 2]

这样就构造完了。

最后,怎样判断是否合法呢?

此时,\(nxt\) 数组便起到作用了。

若当前位为羊,\(s_i\) 为 '\(o\)' 则相邻两位相同,否则不同。

若当前位为狼,\(s_i\) 为 '\(x\)' 则相邻两位相同,否则不同。

判断即可。

合法就输出。

Code:

\(AC\) 记录

#include <bits/stdc++.h>
#define ll long long
#define pii pair <int, int>
using namespace std;
const int N = 1e5 + 10;
int n; string s;
pii nxt[N];
int ans[N];
// 1 羊  2 狼
inline bool check() {
	for (int i = 1; i <= n; ++i) {
		int x = nxt[i].first;
		int y = nxt[i].second;
		if (ans[i]) {
			if (s[i] == 'o') {
				if (ans[x] != ans[y])
					return false;
			} else {
				if (ans[x] == ans[y])
					return false;
			}
		} else {
			if (s[i] == 'x') {
				if (ans[x] != ans[y])
					return false;
			} else {
				if (ans[x] == ans[y])
					return false;
			}
		}
	}
	return true;
}
inline bool solve(int a, int b) {
	ans[1] = a; ans[2] = b;
	if (ans[1] == 1) {
		if (s[1] == 'o') ans[n] = ans[2];
		else ans[n] = 1 - ans[2];
	} else {
		if (s[1] == 'o') ans[n] = 1 - ans[2];
		else ans[n] = 1 - ans[2];
	}
	for (int i = 3; i < n; ++i) {
		if (ans[i - 1] == 1) {
			if (s[i - 1] == 'o') ans[i] = ans[i - 2];
			else ans[i] = 1 - ans[i - 2];
		} else {
			if (s[i - 1] == 'x') ans[i] = ans[i - 2];
			else ans[i] = 1 - ans[i - 2];
		}
	}
	if (check()) return true;
	else return false;
}
inline void write() {
	for (int i = 1; i <= n; ++i) {
		if (ans[i]) printf("S");
		else printf("W");
	}
}
int main() {
	scanf("%d", &n);
	cin >> s;
	s = " " + s;
	for (int i = 1; i <= n; ++i) {
		if (s[i] == 'o') ans[i] = 1;
		else ans[i] = 0;
	}
	nxt[1] = {n, 2};
	nxt[n] = {n - 1, 1};
	for (int i = 2; i < n; ++i)
		nxt[i] = {i - 1, i + 1};
	if (solve(1, 1)) write();
	else if (solve(0, 0)) write();
	else if (solve(1, 0)) write();
	else if (solve(0, 1)) write();
	else printf("-1");
	return 0;
	// Yeah
}

标签:nxt,Menagerie,两位,069,题解,紧邻,int,ans,身份
From: https://www.cnblogs.com/2026zhaoyl/p/18306591

相关文章

  • 题解|2024暑期牛客多校01
    【原文链接】太菜了就先挂4题,其他的写出来了再回来补QwQA.ABitCommon组合数学题目大意题目概括:给定两个整数nnn和m......
  • [题解]POJ2074 Line of Sight
    POJ2074LineofSight题意简述多测。给定若干条线段,全部与\(x\)轴平行。其中有\(2\)条线段表示房子和人行道(虽然翻译不是人行道就是了),保证房子在人行道上面。其他线段表示障碍物(不保证在房子和人行道之间)。请找出人行道上最长的连续部分,使得在这中间可以完整地看到房子的全......
  • 【信道估计】OFDM系统LS和DFT和MMSE信道估计(含信噪比)【含Matlab源码 5069期】
    ✅博主简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,Matlab项目合作可私信或扫描文章底部QQ二维码。......
  • 【信道估计】基于matlab OFDM系统LS和DFT和MMSE信道估计(含信噪比)【含Matlab源码 5069
    ✅博主简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,Matlab项目合作可私信或扫描文章底部QQ二维码。......
  • CF825F String Compression题解
    思路容易想到是个动态规划。首先设\(f_i\)表示字符串前\(i\)个字符所组成的字符串的答案。状态定义好了,接下来就是考虑如何转移了。因为由\(f_i\)可以得到所有\(f_j\),其中\(i+j\lelen\),转移方程为\(f_i=f_j+x\),其中\(x\)为字符串\(i+1\)至\(j\)的最优压缩。接......
  • [ABC347E] Set Add Query题解
    思路通过读题发现,每个数变化当且仅当这个数在集合内。所以不妨设它被添加进来的时间点为\(L_i\),它被删除的时间点为\(R_i\),所以它被增加的数量就是这段时间内集合数量之和。所以用一个变量\(cnt\)模拟当前集合内有多少个数,前缀和维护即可。具体实现参见代码。代码#include<......
  • CF1898D Absolute Beauty 题解
    思路容易发现,如果\(a_i>b_i\)则将\(a_i\)和\(b_i\)交换。在数轴上标出要交换的四个数的位置若线段\(a_ib_i\)和线段\(a_jb_j\)互不相交,此时交换比两条线段处于其他位置时更优。具体证明这里就不再赘述,其他题解讲的已经很清楚了。所以只需交换最大的\(a_i\)和最小......
  • [ABC338E] Chords 题解
    思路思路还是很显然的,简单总结一下思路:首先,将圆环从点\(1\)到\(2N\)切开,并将其拉直成一条直线。在切开状态下,原来的弦变成了直线上的曲线。我们需要判断这些曲线之间是否存在交点。在切开状态下,曲线之间的交点等价于满足\(A_i<A_j<B_i<B_j\)的不同曲线\(i\)和......
  • [ABC258Ex] Odd Steps 题解
    思路拿到这道题,第一时间肯定想到是\(dp\)题目。朴素DP用\(dp_i\)表示序列和为\(i\)的序列个数。因为原数组由奇数组成,所以\(dp\)只可能由\(dp_{i-1}\),\(dp_{i-3}\)等等转移过来,若\(i\inA\),\(dp_i=0\)。即:\[dp_i=\begin{cases}0&i\inA\\dp_{i-1}+dp_{i-3}+\c......
  • CF1859A题解
    CF1859A题解思路考虑一种极端情况,\(b\)数组内的数全部比\(a\)大,这样也无法整除,所以这就是这道题的突破口。我们让\(b\)数组内的数全部比\(a\)里的大,最方便的实现方法就是把原数组内的最大的数放进\(b\)数组,剩下的放进\(a\)数组。注意特判无解情况:原数组内的数一样,这......