NOIP模拟题——神秘大门
【题目描述】
最近小K大牛经过调查发现,在WZland的最南方——WZ Antarctica 出现了奇怪
的磁场反应。为了弄清楚这一现象,小K 大牛亲自出马,来到了WZ Antarctica。
小K大牛发现WZ Antarctica 出现了一道神秘的大门。人总有好奇心,小K大牛想打开
这扇神秘大门,看门的后面究竟是什么东西,但用尽什么办法也不能打开这扇门。
突然,门上出现了一些奇怪的字符。凭着敏锐的直觉,小K 认为这些符号就是打
开这扇门的关键, 于是小K 抓紧时间开始研究这些符号。
经过一些时间的研究,小K 大牛发现这些符号其实是一串密码,只有破解了
这个密码, 才能打开那扇神秘大门。这个密码十分简单,他给出了两个很长的字
符串A 和B,你只需要判断B 是否在A 中出现过就可以了,当然如果B 在A
中出现,那么你还需要输出B 的字符在A 中依次出现的位置。
这里解释一下B 在A 中出现的概念,设A=S1S2…SN,B= T1T2…TM,如果存
在一组数K:K1<K2<…<KM,使得B=SK1SK2…SKM,那么就可以认为B 在A 出现
过。比如说A=sdfesad, B=sfsad,那么B 在A 中出现过,因为B 中的字符在A
中依次出现的位置为1 3 5 6 7。
这个解密过程实在太简单了,于是小K 大牛就将这个任务交给了你。由于小K
大牛十分着急,他只给了你1s 的时间。
【输入】
输入数据包含2 行,分别包含一个字符串,第一行输入的是字符串A,第二
行输入的是字符串B。
【输出】
第一行输出一个字符串“Yes”或“No”,如果B 在A 中出现,那么输出“Yes”,
否则输出“No”。
如果你的第一行输出“Yes”,那么在第接下来若干行你需要输出一组数K,使
得B=SK1SK2…SKM,每行一个数;否则第二行为空。如果存在多组数据满足条件,
你需要输出字典序最大的一组。
【输入输出样例1】
door.in door.out
sdfesad Yes
sfsad 1
3
5
6
7
【输入输出样例2】
door.in door.out
abcdef No
acdefg
【数据范围】
字符串长度1≤n≤1e6
倒着找,向前贪心,一定得到字典序最大或-1。
1 #include<cstdio>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdlib>
5 using namespace std;
6 const int maxn=1e6+7;
7 char a[maxn],b[maxn];
8 int q[maxn];int temp3=0;
9 int temp1,temp2;
10 int main()
11 {
12 freopen("door.in","r",stdin);
13 freopen("door.out","w",stdout);
14 scanf("%s",a);
15 scanf("%s",b);
16 temp1=strlen(a)-1;
17 temp2=strlen(b)-1;
18 while(temp2>=0)
19 {
20 while(a[temp1]!=b[temp2])
21 {
22 temp1--;
23 if(temp1<temp2)
24 {
25 printf("No");
26 exit(0);
27 }
28 }
29 q[++temp3]=temp1;
30 temp2--;temp1--;
31 }
32 printf("Yes\n");
33 for(int i=temp3;i>=1;i--)
34 printf("%d\n",q[i]+1);
35 return 0;
36 }