神秘大门 door 题解

1.神秘大门
(door.pas/c/cpp)
【题目描述】
最近小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。
2
【输出】
第一行输出一个字符串“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


其实这道题直接顺着过就完了,但是值得注意的是字典序最大,意味着我们要从最后开始搞。

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>

using namespace std;

const int maxl = 2e6+5;
char a[maxl],b[maxl];
int c[maxl];
int lena,lenb,tot_c;

void check()
{
	for(int i = lena - 1; i >= 0; i--)
	{
		if(b[--lenb] == a[i])
		{
			c[++tot_c] = i + 1;
			if(lenb == 0) break;
		}
		else lenb++;
	}
	if(lenb == 0)
	{
		printf("Yes\n");
		for(int i = tot_c; i >= 1; i--)
			printf("%d\n",c[i]);
	}
	else printf("No");
}

int main()
{
	freopen("door.in","r",stdin);
	freopen("door.out","w",stdout);
	scanf("%s%s",a,b);
	lena = strlen(a);
	lenb = strlen(b);
	if(lena < lenb) printf("No");
	else check();
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值