建议复制到编译器更好食用。(使用dfs,即深度优先搜索)
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<set>
#include<unordered_map>
using namespace std;
int read()
{
int x=0,y=1;char c=getchar();
while(c>'9'||c<'0'){if(c=='0')y=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*y;
}
int N;
int A[100010],B[100010];
bool vis[100010],st[100010];//vis判断当前小区是否被选, st判断小区在经过一定步骤操作后是否回到该小区
//接上注释,设小区x在被选定后,经过某些步骤后再次选择x小区,构成死循环,即 vis[ x ]==true加上一些操作后,再次选择x小区
bool pan=false;
char str[100010];//小区步骤的字符串存入
bool dfs(int xq,int step){//xq为当前位置小区,step为花费步骤//该方法为置顶向下,(可以理解为树根向树叶的方法)
if(xq>N||xq<1){
return false;//非法步骤
}
if(xq==N){
str[step]='\0';//字符串截止,也是对之前字符串的覆盖
return true;
}
//如果该小区之前已经被选择过
if(vis[xq]){
//陷入死循环,设置状态st,直接返回
st[xq]=true;
return false; //之后没必要再循环下去
}
vis[xq]=true;//该小区被第一次选择
//因为要求字典序最小,其中'\0'<'a'<'b' (如果要求字典序最大,先b再a即可)
//1.先选择走a步骤
if(dfs(xq+A[xq],step+1)){
str[step]='a';//步骤字符填入
if(st[xq]) pan=true;//标志为死循环
return true; //大字典序字符无法覆盖的原因。
//如果小字典序字符满足条件//在此处就已经输出
}
//2.后选择b步骤
if(dfs(xq+B[xq],step+1)){
str[step]='b';
if(st[xq]) pan=true;//标志为死循环
return true;
}
return false;
}
//该方法剪枝//置顶向下剪树枝//简称不撞南墙不回头//
int main(){
scanf("%d",&N);
for(int i=1;i<=N;i++){
scanf("%d",&A[i]);
//该代码中快读方法read()对负数的读入不稳定,不建议在有负数输入的时候使用
}
for(int i=1;i<=N;i++){
scanf("%d",&B[i]);
}
if(dfs(1,0)){
if(pan){
puts("Infinity!");
}
else{
puts(str);
}
}
else{
puts("No solution!");
}
return 0;
}