hdu - 1195 Open the Lock (bfs) && hdu 1973 Prime Path (bfs)

http://acm.hdu.edu.cn/showproblem.php?pid=1195

这道题虽然只是从四个数到四个数,但是状态很多,开始一直不知道怎么下手,关键就是如何划分这些状态,确保每一个状态都能遍历到。

得到四个数之后,分三种情况处理,每次改变一个数之后都要加入队列,最先输出的就是步数最少。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <queue>
 4 using namespace std;
 5 
 6 struct point
 7 {
 8     int f[5];
 9     int step;
10 }s,e;
11 int vis[15][15][15][15];
12 void bfs()
13 {
14     memset(vis,0,sizeof(vis));
15     queue<point>que;
16     s.step=0;
17     que.push(s);
18     vis[s.f[0]][s.f[1]][s.f[2]][s.f[3]]=1;
19     while(!que.empty())
20     {
21         point t=que.front(); que.pop();
22       //  printf("%d %d %d %d %d\n",t.f[0],t.f[1],t.f[2],t.f[3],t.step);
23         if(t.f[0]==e.f[0]&&t.f[1]==e.f[1]&&t.f[2]==e.f[2]&&t.f[3]==e.f[3]) {printf("%d\n",t.step);return;}
24         for(int i=0;i<4;i++)
25         {
26             s=t;
27             if(s.f[i]==9) s.f[i]=1;
28             else s.f[i]++;
29             if(!vis[s.f[0]][s.f[1]][s.f[2]][s.f[3]])
30             {
31                 vis[s.f[0]][s.f[1]][s.f[2]][s.f[3]]=1;
32                 s.step++;
33                 que.push(s);
34             }
35         }
36         for(int i=0;i<4;i++)
37         {
38             s=t;
39             if(s.f[i]==1) s.f[i]=9;
40             else s.f[i]--;
41             if(!vis[s.f[0]][s.f[1]][s.f[2]][s.f[3]])
42             {
43                 vis[s.f[0]][s.f[1]][s.f[2]][s.f[3]]=1;
44                 s.step++;
45                 que.push(s);
46             }
47         }
48         for(int i=0;i<3;i++)
49         {
50             s=t;
51             s.f[i]=t.f[i+1],s.f[i+1]=t.f[i];
52             if(!vis[s.f[0]][s.f[1]][s.f[2]][s.f[3]])
53             {
54                 vis[s.f[0]][s.f[1]][s.f[2]][s.f[3]]=1;
55                 s.step++;
56                 que.push(s);
57             }
58         }
59     }
60 }
61 int main()
62 {
63    // freopen("a.txt","r",stdin);
64     int t;
65     char s1[6],s2[6];
66     scanf("%d",&t);
67     getchar();
68     while(t--)
69     {
70         scanf("%s%s",s1,s2);
71        // printf("%s %s\n",s1,s2);
72         for(int i=0;i<4;i++)
73         {
74             s.f[i]=s1[i]-'0';
75             e.f[i]=s2[i]-'0';
76         }
77         bfs();
78     }
79     return 0;
80 }

 

http://acm.hdu.edu.cn/showproblem.php?pid=1973

这道题很上面那道题一样,也是求一个四位数质数到另一个四位数质数的最小步数,不过这里要求转换的每一步都是质数.

每次只能替换四位中的一位。

我是用了比较笨的方法,把所有情况都找出来。枚举4位数每一位换成0-9中任何一位的情况,然后不断更新一个最小值就行.

#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <string>
#include <set>
#include <functional>
#include <numeric>
#include <sstream>
#include <stack>
#include <map>
#include <queue>
#pragma comment(linker, "/STACK:102400000,102400000")
#define CL(arr, val)    memset(arr, val, sizeof(arr))

#define ll long long
#define inf 0x7f7f7f7f
#define lc l,m,rt<<1
#define rc m + 1,r,rt<<1|1
#define pi acos(-1.0)

#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   (l + r) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)        (1 << (x))
#define iabs(x)     (x) < 0 ? -(x) : (x)
#define OUT(x)  printf("%I64d\n", x)
#define lowbit(x)   (x)&(-x)
#define Read()  freopen("a.txt", "r", stdin)
#define Write() freopen("b.txt", "w", stdout);
#define maxn 1000000000
#define N 2510
#define mod 1000000000
using namespace std;

struct point
{
    int num[5];
    int step;
}s,e;
bool is_prime(int a[])
{
    int n=0;
    n=a[0]*1000+a[1]*100+a[2]*10+a[3];
    //printf("%d\n",n);
    for(int i=2;i*i<=n;i++)
        if(n%i==0) return false;
    return true;
}
int vis[15][15][15][15];
int ans;
void bfs()
{
    memset(vis,0,sizeof(vis));
    queue<point>que;
    s.step=0;
    que.push(s);
    vis[s.num[0]][s.num[1]][s.num[2]][s.num[3]]=1;
    while(!que.empty())
    {
        point t=que.front();que.pop();
        //printf("%d %d %d %d %d\n",t.num[0],t.num[1],t.num[2],t.num[3],t.step);
        if(t.num[0]==e.num[0]&&t.num[1]==e.num[1]&&t.num[2]==e.num[2]&&t.num[3]==e.num[3]&&t.step<ans)
        {
            ans=t.step;
        }
        for(int i=0;i<4;i++)
        {
            for(int j=0;j<10;j++)
            {
                s=t;
                s.num[i]=j;
                if(!(i==0&&j==0)&&!vis[s.num[0]][s.num[1]][s.num[2]][s.num[3]]&&is_prime(s.num)) //注意首位不为0 
                {
                    vis[s.num[0]][s.num[1]][s.num[2]][s.num[3]]=1;
                    s.step=t.step+1;
                    que.push(s);
                }
            }
        }
    }
    if(ans!=inf)
    printf("%d\n",ans);
    else printf("Impossible\n");
}
int main()
{
    //freopen("a.txt","r",stdin);
    int n;
    char s1[6],s2[6];
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s%s",s1,s2);
        for(int i=0;i<4;i++)
        {
            s.num[i]=s1[i]-'0';
            e.num[i]=s2[i]-'0';
            //printf("%d %d\n",s.num[i],e.num[i]);
        }
        if(strcmp(s1,s2)==0) printf("0\n");
        else
        {
            ans=inf;
            bfs();
        }
    }
    return 0;
}

 

posted @ 2015-05-28 20:52  NowAndForever  阅读(139)  评论(0编辑  收藏  举报