洛谷 P5595 【XR-4】歌唱比赛
思路&&代码
这是一道普及-的题目
有一道题和这么一道题很类似,可以先去做这道题,再来做这个,链接:
然后我们来考虑这道题的做法
既然是(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;
}