Atcoder Panasonic Programming Contest 2020 D String Equivalence 难懂的题意+有条件限制的深搜

Panasonic Programming Contest 2020   比赛人数6617   慢,比赛开始后10分钟才看到题目,比赛题目比ABC要灵活些

Atcoder Panasonic Programming Contest 2020  D  String Equivalence   难懂的题意+有条件限制的深搜

总目录详见https://blog.csdn.net/mrcrack/article/details/104454762

在线测评地址https://atcoder.jp/contests/panasonic2020/tasks/panasonic2020_d

题意很难看懂,那先看样例的数据输入于输出:

现在可以讲一讲该题的题意了,

For every string t that is isomorphic to s, s≤t holds. Here ≤ denotes lexicographic comparison.此句最为关键。

也就是在isomorphic对应关系中, s是满足s这种isomorphic类型的字典序最小的字串,不可能找到比s字典序更小的字串了。

以abcac为例

s1!=s2,s1!=s3,s1==s4,s1!=s5

s2!=s3,s2!=s4,s2!=s5

s3!=s4,s3==s5

s4!=s5

满足这种类型的字串,按字典序,有

abcac,abdad,abeae,......,zyxzx

很明显在这种isomorphic对应关系中,字典序最小的是abcac,字典序最大的是zyxzx

在上述这种isomorphic对应关系中,只有字典序最小的abcac是normal form

every string t意思是:即所有的字串t

 

n=1

a,b,c,......,z字典序最小的是a

Input:
1
Output:
a

n=2

aa,bb,cc,......,zz字典序最小的是aa

ab,ac,ad,......,zy字典序最小的是ab

Input:
2
Output:
aa
ab

n=3

aaa,bbb,ccc,......,zzz字典序最小的是aaa

aab,aac,aad,......,zzy字典序最小的是aab

aba,aca,ada,......,zyz字典序最小的是aba

abb,acc,add,......,zyy字典序最小的是abb

abc,abd,ade,......,zyx字典序最小的是abc

Input:
3
Output:
aaa
aab
aba
abb
abc

思路同https://www.cnblogs.com/zdragon1104/p/12496988.html

题解:每一次往后面添一个字母,且该字母不能比之前的最大字母大2。

若还不能理解,读者可以试着手工推出n=4的数据输出,若成功,表明理解了该算法。

Input:
4
Output:
aaaa
aaab
aaba
aabb
aabc
abaa
abab
abac
abba
abbb
abbc
abca
abcb
abcc
abcd
Input:
5
Output:
aaaaa
aaaab
aaaba
aaabb
aaabc
aabaa
aabab
aabac
aabba
aabbb
aabbc
aabca
aabcb
aabcc
aabcd
abaaa
abaab
abaac
ababa
ababb
ababc
abaca
abacb
abacc
abacd
abbaa
abbab
abbac
abbba
abbbb
abbbc
abbca
abbcb
abbcc
abbcd
abcaa
abcab
abcac
abcad
abcba
abcbb
abcbc
abcbd
abcca
abccb
abccc
abccd
abcda
abcdb
abcdc
abcdd
abcde

AC代码如下

#include <cstdio>
#include <algorithm>
using namespace std;
int n,a[15];
void dfs(int step,int pre){//pre记录之前出现的最大字母
	int i,j,now;
	if(step==n){
		for(j=0;j<n;j++)printf("%c",a[j]+'a');
		printf("\n");
		return ;
	}
	now=min(step,pre+1);//当前字母可选范围
	for(i=0;i<=now;i++){
		a[step]=i,pre=max(pre,i);//更新pre
		dfs(step+1,pre);
	}
}
int main(){
	scanf("%d",&n);
	dfs(0,-1);
	return 0;
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值