搜索小练
记得补题
就写了ABCFL
A题(poj1321):做过一次……
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<stack> #include<cmath> using namespace std; #define mem(a,b) memset(a,b,sizeof(a)) #define inf 0x3f3f3f3f #define mod 1000000007 #define ll long long #define rep(i,a,b) for(int i=a;i<=b;i++) const int maxn=10; char g[maxn][maxn]; int vis[maxn][maxn],xx[maxn],yy[maxn]; int n,m,maxx,sum; void dfs(int sum,int r) { if(!sum){ maxx++; return; } for(int i=r;i<n;i++){ if(!xx[i] && n>=(sum+i)){ for(int j=0;j<n;j++){ if(!yy[j]){ if(g[i][j]=='#'&& !vis[i][j]){ yy[j]=1;xx[i]=1;vis[i][j]=1; dfs(sum-1,r+1); yy[j]=0;xx[i]=0;vis[i][j]=0; } } } } } } int main() { while(~scanf("%d%d",&n,&m)){ if(n==-1 && m==-1){break;} for(int i=0;i<n;i++){ scanf("%s",g[i]); xx[i]=0,yy[i]=0; } mem(vis,0); maxx=0; dfs(m,0); printf("%d ",maxx); } return 0; }
B题(poj2251):
题面:找有没有S到E的最短路程,如果没有就输出Trapped!
思路:直接bfs
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> #include<queue> #define mem(a,b) memset(a,b,sizeof(a)) #define inf 0x3f3f3f3f using namespace std; const int maxn=110; char mp[35][35][35]; int vis[35][35][35],n,m,l; int sx,sy,sc,ex,ey,ec,ans; int bu[6]={0,0,0,0,1,-1},bu1[6]={0,0,1,-1,0,0},bu2[6]={1,-1,0,0,0,0}; struct node{ int x,y,c,temp; node(){} node(int xx,int yy,int cc,int t):x(xx),y(yy),c(cc),temp(t){} friend bool operator<(const node a,const node b){ return a.temp>b.temp; } }; int bfs(){ mem(vis,0); priority_queue<node> q; q.push(node(sx,sy,sc,0)); vis[sc][sx][sy]=1; while(!q.empty()){ node tt=q.top();q.pop(); for(int i=0;i<6;i++){ int cc=tt.c+bu[i],xx=tt.x+bu1[i],yy=tt.y+bu2[i],tem=tt.temp+1; //cout<<cc<<xx<<yy<<endl; if(ec==cc && xx==ex && yy==ey){return tem;} if(mp[cc][xx][yy]=='#' || vis[cc][xx][yy] || cc<0 || cc>=l || xx<0 || xx>=n || yy<0 || yy>=m){continue;} vis[cc][xx][yy]=1; q.push(node(xx,yy,cc,tem)); } } return -1; } int main(){ while(~scanf("%d%d%d",&l,&n,&m)){ if(n==0 && m==0 && l==0){break;} for(int i=0;i<l;i++){ //getchar(); for(int j=0;j<n;j++){ scanf("%s",mp[i][j]); for(int k=0;k<m;k++){ if(mp[i][j][k]=='S'){sc=i,sx=j,sy=k;} if(mp[i][j][k]=='E'){ec=i,ex=j,ey=k;} } } //getchar(); } ans=bfs(); if(ans==-1){ printf("Trapped! "); } else{ printf("Escaped in %d minute(s). ",ans); } } return 0; }
C题(poj3278):
题面:有三种操作1. 加一 2 .减一 3 .乘2,一个数字最少需要几步能够另外一个数字(0~1e5)
思路:直接bfs
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> #include<queue> #define mem(a,b) memset(a,b,sizeof(a)) #define inf 0x3f3f3f3f using namespace std; const int maxn=1e5+10; int vis[maxn],n,m,c; struct node{ int x,y; node(){} node(int xx,int yy):x(xx),y(yy){} friend bool operator<(const node a,const node b){ return a.y>b.y; } }; int bfs(){ priority_queue<node> q; q.push(node(n,0)); vis[n]=1; while(!q.empty()){ node k=q.top();q.pop(); int x1=k.x-1,x2=k.x+1,x3=k.x*2,tt=k.y+1; if(x1==m){return tt;} if(x2==m){return tt;} if(x3==m){return tt;} if(x1>=0 && x1<=100000 && !vis[x1]){ vis[x1]=1;q.push(node(x1,tt)); } if(x2>=0 && x2<=100000 && !vis[x2]){ vis[x2]=1;q.push(node(x2,tt)); } if(x3>=0 && x3<=100000 && !vis[x3]){ vis[x3]=1;q.push(node(x3,tt)); } } } int main(){ while(~scanf("%d%d",&n,&m)){ if(n==m){ printf("0 ");continue; } mem(vis,0); printf("%d ",bfs()); } return 0; }
F题(poj3126):
题面:给T组,每组给两个4位数的素数(无前导零),一个素数变换成另一个素数,是按位进行的,比如1033》》1733算一步,求最少需要几次操作
思路:因为只有4位,直接预处理,用链式前向星链接,bfs直接找
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> #include<queue> #include<vector> #define mem(a,b) memset(a,b,sizeof(a)) #define inf 0x3f3f3f3f using namespace std; const int maxn=1e5+10; int mp[maxn]={0},n,m,head[maxn],cnt,vis[maxn]; struct edge{ int n,next; edge(){} edge(int nn,int t):n(nn),next(t){} }a[maxn<<1]; struct node{ int x,t; node(){} node(int xx,int yy):x(xx),t(yy){} friend bool operator<(const node a,const node b){ return a.t>b.t; } }; void upda(int x,int y){ a[cnt]=edge(y,head[x]); head[x]=cnt++; } bool pan(int x){ //int xx=(int)sqrt(x); for(int i=2;i*i<=x;i++){ if(x%i==0){return false;} } return true; } void chuli(int x){ int k=x%10,kk=x/10; for(int i=1;i<=k;i++){ if(mp[x-i]){upda(x,x-i);} } for(int i=1;i<10-k;i++){ if(mp[x+i]){upda(x,x+i);} } k=kk%10,kk/=10; for(int i=1;i<=k;i++){ if(mp[x-i*10]){upda(x,x-i*10);} } for(int i=1;i<10-k;i++){ if(mp[x+i*10]){upda(x,x+i*10);} } k=kk%10,kk/=10; for(int i=1;i<=k;i++){ if(mp[x-i*100]){upda(x,x-i*100);} } for(int i=1;i<10-k;i++){ if(mp[x+i*100]){upda(x,x+i*100);} } k=kk%10; for(int i=1;i<=k;i++){ if(mp[x-i*1000]){upda(x,x-i*1000);} } for(int i=1;i<10-k;i++){ if(mp[x+i*1000]){upda(x,x+i*1000);} } } int bfs() { mem(vis,0); priority_queue<node> q; q.push(node(n,0));vis[n]=1; while(!q.empty()){ node tt=q.top();q.pop(); if(tt.x==m){ return tt.t; } for(int i=head[tt.x];i!=-1;i=a[i].next){ if(!vis[a[i].n]){ vis[a[i].n]=1;q.push(node(a[i].n,tt.t+1)); } } } return -1; } int main(){ cnt=0;mem(head,-1); for(int i=1000;i<10000;i++){ if(pan(i)){ mp[i]=1; } } for(int i=1000;i<10000;i++){ if(mp[i]){ chuli(i); } } int t; while(~scanf("%d",&t)){ for(int i=0;i<t;i++){ scanf("%d%d",&n,&m); printf("%d ",bfs()); } } return 0; }
L题(hdu1495)
题面:给了两个杯子的大小,和可乐的量,问能不能平分,如果能平分,要多少次操作
思路:bfs+倒水问题,看了大佬写法居然是规律题,数论不有点理解不了
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> #include<queue> #include<vector> #define mem(a,b) memset(a,b,sizeof(a)) #define inf 0x3f3f3f3f using namespace std; const int maxn=1e5+10; struct node{ int a,b,s,t; node(){} node(int aa,int bb,int ss,int tt):a(aa),b(bb),s(ss),t(tt){} }cole[110]; int a,b,s; int vis[110][110]; int bfs() { queue<node> q; memset(vis,0,sizeof(vis)); q.push(node(0,0,s,0)); vis[a][b]=1; while(!q.empty()) { node u=q.front(),v; if(u.a==s/2 && u.s==s/2) return u.t; if(u.s && u.a!=a){ int c=a-u.a; if(u.s>=c) v.a=a,v.s=u.s-c; else v.a=u.a+u.s,v.s=0; v.b=u.b; v.t=u.t+1; if(!vis[v.a][v.b]){ q.push(v); vis[v.a][v.b]=1; } } if(u.s && u.b!=b){ int c=b-u.b; if(u.s>=c) v.b=b,v.s=u.s-c; else v.b=u.b+u.s,v.s=0; v.a=u.a; v.t=u.t+1; if(!vis[v.a][v.b]){ q.push(v); vis[v.a][v.b]=1; } } if(u.a && u.s!=s){ int c=s-u.s; if(u.a>=c) v.s=s,v.a=u.a-c; else v.s=u.s+u.a,v.a=0; v.b=u.b; v.t=u.t+1; if(!vis[v.a][v.b]){ q.push(v); vis[v.a][v.b]=1; } } if(u.a && u.b!=b){ int c=b-u.b; if(u.a>=c) v.b=b,v.a=u.a-c; else v.b=u.b+u.a,v.a=0; v.s=u.s; v.t=u.t+1; if(!vis[v.a][v.b]){ q.push(v); vis[v.a][v.b]=1; } } if(u.b && u.a!=a){ int c=a-u.a; if(u.b>=c) v.a=a,v.b=u.b-c; else v.a=u.a+u.b,v.b=0; v.s=u.s; v.t=u.t+1; if(!vis[v.a][v.b]){ q.push(v); vis[v.a][v.b]=1; } } if(u.b && u.s!=s){ int c=s-u.s; if(u.b>=c) v.s=s,v.b=u.b-c; else v.s=u.s+u.b,v.b=0; v.a=u.a; v.t=u.t+1; if(!vis[v.a][v.b]){ q.push(v); vis[v.a][v.b]=1; } } q.pop(); } return 0; } int main() { while(scanf("%d%d%d",&s,&a,&b),s||a||b){ if(s&1){ puts("NO");continue; } if(a<b) swap(a,b); int ans=bfs(); if(ans) printf("%d ",ans); else puts("NO"); } return 0; }
贴一份gcd的写法
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> #include<queue> #include<vector> #define mem(a,b) memset(a,b,sizeof(a)) #define inf 0x3f3f3f3f using namespace std; const int maxn=1e5+10; int gcd(int a, int b) { return b==0?a:gcd(b,a%b); } int main() { int a,b,c; while(~scanf("%d%d%d",&a,&b,&c)) { if(a==0 && b==0 && c==0){break;} a/= gcd(b,c); if(a&1){ printf("NO "); } else{ printf("%d ",a-1); } } }
还剩七道,明天再战
M题(hdu2612):今天早上(28号)发现居然做过!就是bfs即可,那么我还剩七道
#include<iostream> #include<cstring> #include<algorithm> #include<queue> #define inf 0x3f3f3f3f #define sscc ios::sync_with_stdio(false); using namespace std; char mp[205][205]; struct node{ int n; int m; int t; }; int mp2[205][205]; int bu[4] = { 1, -1, 0, 0 }, bu2[4] = { 0, 0, 1, -1 }; bool vis[205][205]; int x, y, n2, m2, mx, my; int minn, kk[1005]; void bfs(int n,int m) { vis[n][m] = true; queue<node>q; node sd, ed; sd.n = n; sd.m = m; sd.t = 0; q.push(sd); while (!q.empty()){ ed = q.front(); q.pop(); if (mp[ed.n][ed.m] == '@' ){ mp2[ed.n][ed.m] += ed.t; } for (int i = 0; i < 4; i++){ sd.n = ed.n + bu[i]; sd.m = ed.m + bu2[i]; sd.t = ed.t + 1; if (sd.n >= 0 && sd.n < n2 && sd.m < m2 && sd.m >= 0 && !vis[sd.n][sd.m] && mp[sd.n][sd.m]!='#'){ vis[sd.n][sd.m] = true; q.push(sd); } } } } int main() { sscc; while (cin>>n2>>m2){ memset(mp2, 0, sizeof(mp2)); memset(vis, false, sizeof(vis)); int ge = 0; minn = inf; for (int i = 0; i < n2; i++){ for (int j = 0; j < m2; j++){ cin >> mp[i][j]; if (mp[i][j] == 'Y'){ x = i; y = j; //cout << x << y << endl; } else if (mp[i][j] == 'M'){ mx = i; my = j; //cout << mx << my << endl; } else if (mp[i][j] == '@'){ kk[ge++] = i; kk[ge++] = j; } } } bfs(x, y); memset(vis, false, sizeof(vis)); bfs(mx, my); for (int i = 0; i < n2; i++){ for (int j = 0; j < m2; j++){ if (minn > mp2[i][j] && mp2[i][j] != 0){ minn = mp2[i][j]; } } } cout << minn * 11 << endl; } return 0; }
K题(poj3984):是个笨比题,就是存路就行了(7/13)
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cmath> 5 #include<algorithm> 6 #include<queue> 7 #include<vector> 8 #include<string> 9 #define mem(a,b) memset(a,b,sizeof(a)) 10 #define inf 0x3f3f3f3f 11 using namespace std; 12 const int maxn=1e5+10; 13 int a[6][6],vis[6][6]={0}; 14 int bu[4]={0,0,1,-1},bu1[4]={1,-1,0,0}; 15 struct node{ 16 int x,y,t; 17 string s; 18 node(){} 19 node(int xx,int yy,int tt,string ss):x(xx),y(yy),t(tt),s(ss){} 20 friend bool operator<(const node a,const node b){ 21 return a.t>b.t; 22 } 23 }; 24 string bfs() 25 { 26 priority_queue<node> q; 27 q.push(node(0,0,0,"")); 28 vis[0][0]=1; 29 while(!q.empty()){ 30 node tt=q.top();q.pop(); 31 if(tt.x==4 && tt.y==4){ 32 return tt.s; 33 } 34 for(int i=0;i<4;i++){ 35 int xx=tt.x+bu[i],yy=tt.y+bu1[i],t1=tt.t+1; 36 char b='0'+i; 37 string bb=tt.s+b; 38 if(xx>=0 && xx<5 && yy>=0 && yy<5 && !vis[xx][yy] && !a[xx][yy]){ 39 vis[xx][yy]=1; 40 q.push(node(xx,yy,t1,bb)); 41 } 42 } 43 } 44 } 45 int main(){ 46 for(int i=0;i<5;i++){ 47 for(int j=0;j<5;j++){ 48 scanf("%d",&a[i][j]); 49 } 50 } 51 string c=bfs(); 52 int l=c.size(); 53 printf("(0, 0) "); 54 int sx=0,sy=0; 55 for(int i=0;i<l;i++){ 56 sx+=bu[c[i]-'0'];sy+=bu1[c[i]-'0']; 57 printf("(%d, %d) ",sx,sy); 58 } 59 return 0;
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> #include<queue> #include<vector> #include<string> #define mem(a,b) memset(a,b,sizeof(a)) #define inf 0x3f3f3f3f using namespace std; const int maxn=1e5+10; int a[6][6],vis[6][6]={0}; int bu[4]={0,0,1,-1},bu1[4]={1,-1,0,0}; struct node{ int x,y,t; string s; node(){} node(int xx,int yy,int tt,string ss):x(xx),y(yy),t(tt),s(ss){} friend bool operator<(const node a,const node b){ return a.t>b.t; } }; string bfs() { priority_queue<node> q; q.push(node(0,0,0,"")); vis[0][0]=1; while(!q.empty()){ node tt=q.top();q.pop(); if(tt.x==4 && tt.y==4){ return tt.s; } for(int i=0;i<4;i++){ int xx=tt.x+bu[i],yy=tt.y+bu1[i],t1=tt.t+1; char b='0'+i; string bb=tt.s+b; if(xx>=0 && xx<5 && yy>=0 && yy<5 && !vis[xx][yy] && !a[xx][yy]){ vis[xx][yy]=1; q.push(node(xx,yy,t1,bb)); } } } } int main(){ for(int i=0;i<5;i++){ for(int j=0;j<5;j++){ scanf("%d",&a[i][j]); } } string c=bfs(); int l=c.size(); printf("(0, 0) "); int sx=0,sy=0; for(int i=0;i<l;i++){ sx+=bu[c[i]-'0'];sy+=bu1[c[i]-'0']; printf("(%d, %d) ",sx,sy); } return 0; }
E题(poj1426):一开始以为会爆longlong,想着大数除法又不太会,好难,后来发现根本不会爆,顺手更深的了解了unsigned
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> #include<queue> #include<vector> #include<string> #define mem(a,b) memset(a,b,sizeof(a)) #define inf 0x3f3f3f3f #define ll long long using namespace std; const int maxn=1e5+10; int a[6][6],vis[6][6]={0}; int bu[4]={0,0,1,-1},bu1[4]={1,-1,0,0}; struct node{ int x,y,t; string s; node(){} node(int xx,int yy,int tt,string ss):x(xx),y(yy),t(tt),s(ss){} friend bool operator<(const node a,const node b){ return a.t>b.t; } }; bool flag; void dfs(unsigned ll t, int n, int k){ if (flag) return; if (t%n == 0){ printf("%llu ", t); flag= true; return; } if (k == 19) return; dfs(t * 10, n, k + 1); dfs(t * 10 + 1, n, k + 1); } int main() { int n; while (~scanf("%d",&n)){ if(n==0)break; flag = false; dfs(1, n, 0); } return 0; }
I题(poj2150):有两个人烧草堆,如果能烧完输出最少时间,不能就输出-1,因为没有特判只有一个的草堆的情况,所以wa了两次,还pe了一次……
因为数据小,所以直接暴力了
#include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> #include<queue> #include<vector> #include<string> #define mem(a,b) memset(a,b,sizeof(a)) #define inf 0x3f3f3f3f #define ll long long using namespace std; const int maxn=1e5+10; int vis[15][15],a[400]; char mp[15][15]; int n,m,ge; int bu[4]={0,0,1,-1},bu1[4]={1,-1,0,0}; struct node{ int x,y,t; node(){} node(int xx,int yy,int tt):x(xx),y(yy),t(tt){} friend bool operator<(const node a,const node b){ return a.t>b.t; } }; int bfs(int x1,int y1,int x2,int y2){ mem(vis,0);int k=2,maxbu=0;//cout<<x1<<y1<<x2<<y2<<endl; priority_queue<node>q; q.push(node(x1,y1,0));q.push(node(x2,y2,0)); vis[x1][y1]=vis[x2][y2]=1; while(!q.empty()){ node tt=q.top();q.pop(); if(k==ge){ return maxbu; } for(int i=0;i<4;i++){ int xx=tt.x+bu[i],yy=tt.y+bu1[i],te=tt.t+1; if(xx>=0&&xx<n&&yy>=0&&yy<m&&!vis[xx][yy]&&mp[xx][yy]=='#'){ maxbu=max(te,maxbu); k++;vis[xx][yy]=1;q.push(node(xx,yy,te));//cout<<xx<<" "<<k<<" "<<maxbu<<endl; if(k==ge){ return maxbu; } } } } return -1; } int main() { int t,c=1; scanf("%d",&t); while(t--){ ge=0; int ans=-1; scanf("%d%d",&n,&m); for(int i=0;i<n;i++){ scanf("%s",mp[i]); } for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(mp[i][j]=='#'){ a[ge++]=i*100+j; } } } if(ge==1){ printf("Case %d: 0 ",c++);continue; } //cout<<ge<<endl; for(int i=0;i<ge;i++){ for(int j=i+1;j<ge;j++){ int k=bfs(a[i]/100,a[i]%100,a[j]/100,a[j]%100); if(ans==-1 && k!=-1){ ans=k; } else if(k!=-1){ ans=min(ans,k); } } } printf("Case %d: %d ",c++,ans); } return 0; }