洛谷 P5595 【XR-4】歌唱比赛

洛谷 P5595 【XR-4】歌唱比赛

思路&&代码

这是一道普及-的题目

有一道题和这么一道题很类似,可以先去做这道题,再来做这个,链接:

(P3742 umi)的函数

然后我们来考虑这道题的做法

既然是(special judge),我们就可以直接乱搞了,只用(0)(1)两个数,我们就可以(A)掉它啦~~

拿到题目的第一眼其实是有一点点懵逼的,然后读一读就会发现并不难,我们很容易就可以想到一个思路:从前往后扫,如果此时的字符为(X),那就让(X)这个数的这一位比(Y)大,如果此时的字符为(Y),那就让(Y)这个数的这一位比(X)大,如果此时的字符为(Z),那么就让(X)(Y)两个数的这一位相等

思路简直不要太完美

然后我兴高彩烈的交了一发,(74)

为什么??因为没有判断无解的情况,我忘记了还有样例(4)这种无解的情况,这是我最菜的地方……

那么我们来看一下,什么样的情况才算无解

其实这个也比较明显,就像下面这种情况(XXXZZYYZ),如果前面出现了一个(Z),而后面不是(Z),但之后又出现了(Z),就是无解,为什么呢?因为按照题意来说,(Z)表示的是:从(Z)这一位开始后面所有的数字都是相等的,即到目前为止(X)(Y)两数相等。如果前面有了(Z),而中间又有了(X)(Y),很明显是不对的,所以我们就可以先(O(n))判断一下会不会出现无解的情况,代码如下

for(int i = 1; i <= len; i++) {
		if(s[i] == 'Z') now = 1;//now表示有没有Z
		if(s[i] != 'Z' && now) return cout << "-1
", 0;
        //如果从前往后扫,已经出现了Z,后面就不能再出现X或Y,如果出现,即是无解
	}

然后就做完了,完整的代码如下

/*
By:Loceaner
*/
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

inline int read() {
	char c = getchar();
	int x = 0, f = 1;
	for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
	for( ; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + (c ^ 48);
	return x * f;
}

const int N = 1e6 + 11;

char s[N], a[N], b[N];
int now;

int main() {
	scanf("%s", s + 1);
	int len = strlen(s + 1);
	for(int i = 1; i <= len; i++) {
		if(s[i] == 'Z') now = 1;
		if(s[i] != 'Z' && now) return cout << "-1
", 0;
	}
	for(int i = 1; i <= len; i++) {
		if(s[i] == 'X') a[i] = '1', b[i] = '0';
		else if(s[i] == 'Y') a[i] = '0', b[i] = '1';
		else if(s[i] == 'Z') a[i] = '1', b[i] = '1';
	}
	printf("%s
%s", a + 1, b + 1);
	return 0;
}

原文地址:https://www.cnblogs.com/loceaner/p/11711331.html