题目思想其实很简单,直接搜索就可以了,因为由题意可以直接转化成一幅图,比较不好处理的就是Infinity的情况,不过这题数据较水,所以就算直接暴力不加任何优化的搜索都可以拿九十分,不过如果要想完全正确的话,暴搜肯定不行。这里我用的方法是先进行一次逆向搜索,标记可以到达终点的点,然后在进行一次正向搜索,尽可能选择a,如果a不行再选b,搜索过程中如果发现有点重复访问,则说明出现了环,也就是Infinity的情况。
代码:
//It is made by HolseLee on 23rd Jan 2018 //LSOI T3 #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #include<vector> using namespace std; const int N=100010; int n,len,a[N],b[N]; bool vt[N],vis[N]; vector<int>team[N]; char s[N<<1]; inline int read() { char ch=getchar();int num=0;bool flag=false; while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)flag=true;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){num=num*10+ch-‘0‘;ch=getchar();} return flag?-num:num; } inline void check(int x) { if(vt[x])return; vt[x]=true; for(vector<int>::iterator it=team[x].begin();it!=team[x].end();it++) check(*it); } inline bool dfs(int x,int num) { if(x==n){len=num;return true;} if(vis[x])return false;vis[x]=true; if(1<=x+a[x]&&x+a[x]<=n&&vt[x+a[x]]){ if(dfs(x+a[x],num+1)==false)return false; else {s[num]=‘a‘;return true;}} if(1<=x+b[x]&&x+b[x]<=n&&vt[x+b[x]]){ if(dfs(x+b[x],num+1)==false)return false; else {s[num]=‘b‘;return true;}} } void ready() { memset(vis,false,sizeof(vis)); memset(vt,false,sizeof(vt)); n=read(); for(int i=1;i<=n;i++){ a[i]=read(); if(1<=i+a[i]&&i+a[i]<=n) team[i+a[i]].push_back(i); } for(int i=1;i<=n;i++){ b[i]=read(); if(1<=i+b[i]&&i+b[i]<=n) team[i+b[i]].push_back(i); } } void work() { check(n); if(!vt[1])printf("No solution!"); else{ if(dfs(1,0)==false)printf("Infinity!"); else s[len]=0,printf("%s",s); } } int main() { freopen("grid.in","r",stdin); freopen("grid.out","w",stdout); ready(); work(); return 0; }