POJ 1321 1426 3126 3087 3414
蒻苣:弱弱很弱,路过的巨巨还不吝赐教!^.^...QAQ
五道水搜索。。。
好像基本都是BFS水过的。。好像luluDFS啊。。。
POJ 1321 棋盘问题
链接:http://poj.org/problem?id=1321
题意:中文题
题解:DFS。八皇后问题吧。。限制不同而已。。
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 #define maxn 10 8 int pre[maxn][maxn]; 9 int sum,n,k ; 10 int lazy[maxn]; 11 void dfs(int cur,int num) 12 //用num代表放了几个球了,cur代表当前搜索行 13 { 14 int i,j,t; 15 if( num == k ) 16 { 17 sum++; 18 return; 19 } 20 if(cur>n) 21 return ; 22 for(i = 1; i <= n ; i++) //第cur个的列数; 23 if(pre[cur][i]&&!lazy[i]) 24 { 25 lazy[i] = 1; 26 dfs(cur+1,num+1); 27 lazy[i] = 0; 28 } 29 30 dfs(cur+1,num); 31 32 } 33 34 int main() 35 { 36 char c; 37 int m; 38 int i,j; 39 while(~scanf("%d%d",&n,&k)) 40 { 41 memset(lazy,0,sizeof(lazy)); 42 memset(pre,0,sizeof(pre)); 43 int count = 0; 44 sum = 0; 45 if(n == -1&& k == -1) break; 46 for(i = 1; i <= n;i++) 47 for(j = 1;j <=n ; j++) 48 { 49 cin>>c; 50 if(c == '.') 51 pre[i][j] = 0; 52 else 53 { 54 pre[i][j] = 1; 55 count++; 56 } 57 } 58 if(count<k) 59 printf("0\n"); 60 else if(k == 1) 61 printf("%d\n",count); 62 else 63 { 64 dfs(1,0); 65 cout<<sum<<endl; 66 } 67 } 68 }
POJ 1426
链接:http://poj.org/problem?id=1426
题意:给你个m,求m的倍数,数字只能01组成。。
题解:暴力DFS一发水过。。。看网上是用什么同于取模过的。。。大概算了一下是不会爆long long的。。样例纯属吓唬人。。SPJ。。
代码
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 int k; 6 bool dfs(int cnt,long long sum) 7 { 8 if(cnt > 18) return false; 9 if(sum % k == 0) { printf("%lld\n",sum);return true;} 10 if(dfs(cnt+1,sum*10+1)) return true; 11 if(dfs(cnt+1,sum*10)) return true; 12 return false; 13 } 14 int main() 15 { 16 while(scanf("%d",&k) != EOF) 17 { 18 if(k == 0) break; 19 dfs(0,1); 20 } 21 return 0; 22 }
POJ 3126
链接:http://poj.org/problem?id=3126
题意:给个四位数质数,每次变其中一位数,最少变几次能够变成目标质数。
题解:先是TLE了一发,原因是打表之后发现素数是1000个左右(一千口入)。。天真以为4*1000*1000次不会超(test太多吧)。。然后换了一种方式 变成36口入了。
做法就是:从给定初始质数开始,改变千位、百位、十位、个位。改变从0-9。。就变成36口入了。。。这样也跑了188ms...
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 #include<queue> 7 using namespace std; 8 9 const int MAXN = 100000; 10 bool prime[MAXN+1]; 11 void getPrime() 12 { 13 memset(prime,0,sizeof(prime)); 14 for(int i = 1000;i <= 10000;i++ ) 15 { 16 int j; 17 for( j = 2;j<i;j++) 18 { 19 if(i%j == 0) 20 { 21 prime[i] = false; 22 break; 23 } 24 } 25 if(j == i) 26 prime[i] = true; 27 } 28 } 29 //169~1229 30 31 32 33 struct st{ 34 int x; 35 int t; 36 }f; 37 int vis[10000]; 38 int bfs(int n,int m) 39 { 40 int tt[5]; 41 f.x = n; 42 f.t = 0; 43 queue<st>que; 44 que.push(f); 45 while(!que.empty()) 46 { 47 st g; 48 f = que.front(); 49 que.pop(); 50 vis[f.x] = 1; 51 tt[0] = f.x/1000; 52 tt[1] = (f.x/100)%10; 53 tt[2] = (f.x/10)%10; 54 tt[3] = f.x%10; 55 for(int i = 0; i < 4; i++ ) 56 { 57 int temp = tt[i]; 58 for(int j= 0;j<=9;j++) 59 { 60 if(j!=tt[i]) 61 { 62 tt[i] = j; 63 int kk = tt[0]*1000+tt[1]*100+tt[2]*10+tt[3]; 64 if(!vis[kk]&&prime[kk]) 65 { 66 g.x = kk; 67 g.t = f.t+1; 68 que.push(g); 69 if(g.x == m) 70 return g.t; 71 vis[kk] = 1; 72 } 73 } 74 tt[i] = temp; 75 } 76 } 77 } 78 } 79 80 int main() 81 { 82 getPrime(); 83 int test; 84 scanf("%d",&test); 85 int n,m; 86 while(test--) 87 { 88 memset(vis,0,sizeof(vis)); 89 scanf("%d %d",&m,&n); 90 if(m==n) 91 printf("0\n"); 92 else 93 { 94 printf("%d\n",bfs(n,m)); 95 } 96 } 97 }
POJ 3087
链接:http://poj.org/problem?id=3087
题意:给你两堆牌。交叉洗。洗多少次 变成第三个字符串那样
题解:模拟洗牌。。。(DFS应该也行,或者1口如BFS)加个判断即可
代码
1 #include<iostream> 2 #include<string> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cstring> 6 #include<map> 7 using namespace std; 8 int main() 9 { 10 int test; 11 int t=0; 12 cin>>test; 13 int Case = 0; 14 while(test--) 15 { cout<<++Case; 16 map<string,int>vist; 17 int len; 18 cin>>len; 19 char s1[500],s2[500],ss[500]; 20 int sum=0; 21 cin>>s1>>s2>>ss; 22 vist[ss]=1; 23 while(1) 24 { 25 char s[201]; 26 int k,i; 27 k=0; 28 for(i=0;i<len;i++) 29 { 30 s[k++]=s2[i]; 31 s[k++]=s1[i]; 32 } 33 sum++; 34 if(strcmp(s,ss) == 0) 35 { 36 cout<<' '<<sum<<endl; 37 break; 38 } 39 if(vist[s] && strcmp(s,ss)) 40 { 41 cout<<' '<<-1<<endl; 42 break; 43 } 44 memset(s1,0,sizeof(s1)); 45 memset(s1,0,sizeof(s2)); 46 vist[s]=1; 47 for(i=0;i<len;i++) s1[i]=s[i]; 48 for(k=0;i<2*len;i++,k++) s2[k]=s[i]; 49 } 50 } 51 return 0; 52 }
POJ 3414 Pots
链接:http://poj.org/problem?id=3414
题意:和非常可乐有点类似。给你两种杯子1,2,和一个整数c,三种操作 装满i 倒光i,将i倒入j。输出当任一杯子里的水==c时的最小操作数
题解:六口入BFS+回溯打印路径
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 #define F(i) printf("FILL(%d)\n",i) 8 #define D(i) printf("DROP(%d)\n",i) 9 #define P(i,j) printf("POUR(%d,%d)\n",i,j) 10 struct st{ 11 int x,y; 12 int k; 13 }step[105][105]; 14 queue<st> que; 15 struct p{ 16 int a,b; 17 int t; 18 }; 19 queue<p> q; 20 int vis[100+5][105]; 21 int x,y; 22 st l[10000]; 23 int ff(int a,int b, int fa,int fb,int i,int k) 24 { 25 if(i==1) //装a 26 { 27 if(k==1) return a; 28 else return fb; 29 } 30 if(i==2)//装b 31 { 32 if(k==1) return fa; 33 if(k==2) return b; 34 } 35 if(i==3)//倒a 36 { 37 if(k==1) return 0; 38 else return fb; 39 } 40 if(i==4)//倒b 41 { 42 if(k==1) return fa; 43 return 0; 44 } 45 if(i==5)//a->b 46 { 47 int kk=0; 48 if(k==1){ 49 int ss = fa+fb; 50 fb+=fa; 51 if(fb>b) return ss-b; 52 return 0; 53 } 54 else { 55 fb+=fa; 56 if(fb>b)return b; 57 return fb; 58 } 59 } 60 if(i==6)//b->a 61 { 62 int kk=0; 63 if(k==1){ 64 fa+=fb; 65 if(fa>a) return a; 66 return fa; 67 } 68 else { 69 int ss = fa+fb; 70 fa+=fb; 71 if(fa>a)return ss-a; 72 return 0; 73 } 74 } 75 } 76 int bfs(int a,int b,int c) 77 { 78 p f; 79 f.a = 0; 80 f.b = 0; 81 f.t = 0; 82 q.push(f); 83 step[f.a][f.b].x=f.a; 84 step[f.a][f.b].y=f.b; 85 while(!q.empty()) 86 { 87 f = q.front(); 88 q.pop(); 89 p g; 90 for(int i = 0;i<6;i++) 91 { 92 g.a = ff(a,b,f.a,f.b,i+1,1); 93 g.b = ff(a,b,f.a,f.b,i+1,2); 94 g.t = f.t + 1; 95 if(!vis[g.a][g.b]) 96 { 97 98 vis[g.a][g.b] = 1; 99 step[g.a][g.b].x = f.a; 100 step[g.a][g.b].y = f.b; 101 step[g.a][g.b].k = i+1; 102 q.push(g); 103 if(g.a==c||g.b==c){ 104 x = g.a; 105 y = g.b; 106 return g.t; 107 } 108 109 } 110 } 111 } 112 return -1; 113 } 114 115 int main() 116 { 117 int a,b,c; 118 cin>>a>>b>>c; 119 int sum = -1; 120 sum = bfs(a,b,c); 121 if(sum==-1){puts("impossible");return 0;} 122 cout<<sum<<endl; 123 int j = 0; 124 while((step[x][y].x!=x)||(step[x][y].y!=y)) 125 { 126 l[j].x=step[x][y].x; 127 l[j].y=step[x][y].y; 128 l[j].k=step[x][y].k; 129 int t = x; 130 x = step[x][y].x; 131 y = step[t][y].y; 132 j++; 133 } 134 for(int i = j-1;i>=0;i--) 135 { 136 if(l[i].k == 1) F(1); 137 if(l[i].k == 2) F(2); 138 if(l[i].k == 3) D(1); 139 if(l[i].k == 4) D(2); 140 if(l[i].k == 5) P(1,2); 141 if(l[i].k == 6) P(2,1); 142 } 143 return 0; 144 }
浙公网安备 33010602011771号