2014 UESTC暑前集训搜索专题解题报告
A.解救小Q
BFS。每次到达一个状态时看是否是在传送阵的一点上,是则传送到另一点即可。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> using namespace std; #define NA 100007 char mp[52][52]; struct status { int x,y; int l; }; int vis[52][52]; struct transport { int x1,y1; //初始点 int x2,y2; //传送目标点 int flag; }a[27]; int n,m; int head,tail; int pathx[4]={0,1,0,-1}; int pathy[4]={-1,0,1,0}; bool OK(int nx,int ny) { return nx>=0&&ny>=0&&nx<n&&ny<m; } int bfs(int x,int y) { status now,next; queue<status> que; now.x=x; now.y=y; now.l=0; vis[now.x][now.y]=1; que.push(now); while(!que.empty()) //队列非空 { now = que.front(); que.pop(); for(int i=0;i<4;i++) { int nx=now.x+pathx[i]; int ny=now.y+pathy[i]; if(vis[nx][ny] || !OK(nx,ny)) continue; if(mp[nx][ny]=='Q') return now.l+1; if(mp[nx][ny]!='#') { if(mp[nx][ny]>='a'&&mp[nx][ny]<='z') { int h=mp[nx][ny]-'a'; if(a[h].x1!=nx||a[h].y1!=ny) //初始点和目标点可以互换 { next.x=a[h].x1; next.y=a[h].y1; } else { next.x=a[h].x2; next.y=a[h].y2; } next.l=now.l+1; que.push(next); } else { next.x=nx; next.y=ny; next.l=now.l+1; que.push(next); } vis[nx][ny]=1; } } } return -1; } int main() { int T,x,y; int N,M; scanf("%d",&T); while(T--) { memset(vis,0,sizeof(vis)); memset(mp,0,sizeof(mp)); for(int j=0;j<27;j++) a[j].flag=0; scanf("%d%d",&N,&M); n=N; m=M; getchar(); for(int i=0;i<N;i++) { for(int j=0;j<M;j++) { scanf("%c",&mp[i][j]); if(mp[i][j]=='L') { x=i; y=j; } if(mp[i][j]>='a'&&mp[i][j]<='z') { int h=mp[i][j]-'a'; if(a[h].flag==0) { a[h].x1=i; a[h].y1=j; a[h].flag=1; } else if(a[h].flag==1) { a[h].x2=i; a[h].y2=j; } } } getchar(); } printf("%d ",bfs(x,y)); } return 0; }
B.方老师开橙卡
每次枚举一位数,从1位数字到9位数字,满足条件则加入队列。比如21,首先1*1 = 1 和 9*9 = 81 都满足个位与21的个位相同,加入队列,下次就考虑匹配第二位,然后第三位,。。每次去除相同位数的数字(que.size()),比如去除Y,则拓展的时候枚举X,这时m=10*X+Y,看此时m^2的那一位是否与n的那一位匹配,如果匹配,则加入队列。每次如果相等,顺便判断一下是否就是n,就是的话直接与答案相比,小于答案则更新答案。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #define Mod 1000000007 using namespace std; #define N 50007 int Scheck(ll ka,ll n) { while(ka && n) { if(ka%10 != n%10) return 0; ka/=10; n/=10; } if(n == 0) return 1; else return 0; } ll Ten(int wei) { ll res = 1; for(int i=0;i<wei;i++) res *= 10; return res; } ll toTen(ll tmp) { ll res = 1; while(tmp) { res *= 10; tmp /= 10; } return res; } ll ans; int w[12],ind; void BFS(ll n) { queue<ll> que; ll m,x,y; for(y=0;y<=9;y++) { ll ka = y*y; if(ka%10 == w[1]) { if(Scheck(ka,n)) { if(y < ans) ans = y; } else que.push(y); } } int layer = 1; while(!que.empty()) { layer++; if(layer > 10 || layer >= ind) return; ll ten = Ten(layer-1); int qsize = que.size(); while(qsize--) { ll tmp = que.front(); que.pop(); for(x=0;x<=9;x++) { m = ten*x+tmp; ll m2 = m*m; if((m2/ten)%10 == w[layer]) { if(Scheck(m2,n)) { if(m < ans) ans = m; } else que.push(m); } } } } return; } int main() { int T; ll n; scanf("%d",&T); while(T--) { scanf("%lld",&n); if(n == 0) { printf("0 "); continue; } ll kn = n; ind = 1; while(kn) { w[ind++] = kn%10; kn/=10; } ans = Mod; BFS(n); if(ans == Mod) puts("None"); else printf("%lld ",ans); } return 0; }