WING \operatorname{WING} WING
题目链接: SSL比赛 1503 \operatorname{SSL比赛\ 1503} SSL比赛 1503
题目
输入
输出
样例输入
让你复制:
5 5
1 WINGG
0 WINGG
1 WINGG
0 GGGGG
1 WIGGG
样例输出
-1
1
2
数据范围
对于 40 % 40\% 40% 的数据满足: n < = 5 , c < = 1000 ; n<=5,c<=1000; n<=5,c<=1000;
对于 100 % 100\% 100% 的数据满足: n < = 10 ; c < = 1 0 6 ; n<=10;c<=10^6; n<=10;c<=106;
思路
这道题是一道暴力题吧。
我们可以发现,只要给出的序列在一个位置上是这个字母,就一定能在这个位置拼出这个字母。
(md我还以为两个序列合并完就被拆开了,用不了了,搞得我一直不敢打这个方法,gàn! )
那我们就统计这个位置这个字母第一次出现是在什么时候。对于要拼的一个序列,如果有一个位置的字母所有的序列在这个位置都没有,就拼不出来。如果拼的出来,答案就是序列每一个位置的字母第一次出现的时间的最大值。(即每个位置的那个字母在那个位置出现的时间最晚的一个)
就没了。
(记得要用快读快输,不用 60 60 60 分,加了快读 70 70 70 ,两个都加才 100 100 100 )
代码
#include<cstdio>
#include<iostream>
using namespace std;
int n, m, x, a[1000001][11], num, fir[5][11], ans, now;
char c, cant;
int read() {
//快读
int an = 0, zhengfu = 1;
c = getchar();
while (c < '0' || c > '9') {
if (c == '-') zhengfu = -zhengfu;
c = getchar();
}
while (c >= '0' && c <= '9') {
an = an * 10 + c - '0';
c = getchar();
}
return an * zhengfu;
}
void writec(int x) {
//快输
if (x > 9) writec(x / 10);
putchar(x % 10 + '0');
}
void write(int x) {
if (x < 0) {
putchar('-');
writec(-x);
putchar('\n');
return ;
}
writec(x);
putchar('\n');
}
int main() {
n = read();//读入
m = read();
for (int i = 1; i <= m; i++) {
x = read();//读入
c = getchar();
while (c != 'W' && c != 'I' && c != 'N' && c != 'G') c = getchar();
if (!x) {
num++;//加入新的串
for (int j = 1; j <= n; j++) {
if (c == 'W') a[num][j] = 1;
else if (c == 'I') a[num][j] = 2;
else if (c == 'N') a[num][j] = 3;
else a[num][j] = 4;
if (!fir[a[num][j]][j])//这个字母在这个位置第一次出现
fir[a[num][j]][j] = num;//记录这个字母在这个位置第一次出现的位置
c = getchar();
}
}
else {
//求值
ans = 0;//初始化
cant = 0;
for (int j = 1; j <= n; j++) {
if (c == 'W') now = 1;
else if (c == 'I') now = 2;
else if (c == 'N') now = 3;
else now = 4;
if (!fir[now][j]) {
//这个地方没有出现过这个字母
cant = 1;
}
else ans = max(ans, fir[now][j]);//找到最晚出现的位置
c = getchar();
}
if (!cant) write(ans);//输出
else write(-1);
}
}
return 0;
}
后记
讲题的大佬把时间改成了 3 3 3 秒,好像不加快读快输都能 A A A 了。