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 }
View Code

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 }
View Code


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 }
View Code


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 }
View Code

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 }
View Code

 

posted on 2015-08-17 22:39  小松song  阅读(147)  评论(0)    收藏  举报

导航