zoukankan      html  css  js  c++  java
  • POJ 3126 Prime Path(BFS求“最短路”)

    题意:给出两个四位数的素数,按如下规则变换,使得将第一位数变换成第二位数的花费最少,输出最少值,否则输出0。      

      每次只能变换四位数的其中一位数,使得变换后的数也为素数,每次变换都需要1英镑(即使换上的数是以前被换下的)。

    思路:若素数a可以按上述规则转化为b,则可以看做a、b直接有一条边。显然,从初始值到目标值的路径上的边数即为花费的      

       数目,这样一来,就相当于求最短路径。由于题目只要求最小花费数,所以不需要存储有向图。      

      用BFS搜索,每次枚举当前值x所能变换得到的值y,若y满足条件,将y以及从初始值达到当前y值所需要的次数压入队列。      

      只要当从队列取出的数值等于目标值,此时的花费即为答案,结束循环。

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    int start,goal,t;//start:初始值,goal:目标值
    int prime[10001];
    int vis[10001];//标记数i是否之前已经被转换过
    
    struct Node{
        int num;
        int step; //从start变为num所需要的步数
    };
    
    //将x的第i位的值改成j
    int change(int x,int i,int j){
        if(i==1)
            return x-x%10+j;
        if(i==2)
            return (x/100)*100+x%10+j*10;
        if(i==3)
            return (x/1000)*1000+x%100+j*100;
        if(i==4)
            return x%1000+j*1000;
        return 0;
    }
    
    
    int bfs(int start,int ends){
        queue<Node> q;
        Node a,b;
        vis[start]=1;
        a.num=start;
        a.step=0;
        q.push(a);
        while(!q.empty()){
            a=q.front();
            q.pop();
            //只要a.num等于目标值的话,就退出循环。
            //因为不可能有比这花费最少的情况了。
            if(a.num==ends){
                return a.step;
            }
            vis[a.num]=1;
            //枚举
            for(int i=1;i<=4;i++){
                for(int j=0;j<=9;j++){
                    //若为偶数,直接继续
                    if(i==1 && j%2==0)
                        continue;
                    if(i==4&&j==0)
                        continue;
                    int temp=change(a.num,i,j);
                    if(prime[temp]==0 || vis[temp])
                        continue;
                    b.num=temp;
                    b.step=a.step+1;
                    q.push(b);
                }
            }
    
        }
        return -1;
    }
    //预处理1000~9999的素数
    void dealWithPrime(){
        memset(prime,1,sizeof(prime));
        for(int i=2;i<10000;i++){
            if(prime[i]){
                for(int j=i*i;j<10000;j+=i){
                    prime[j]=0;
                }
            }
        }
    }
    
    int main()
    {
        dealWithPrime();
        scanf("%d",&t);
        for(int i=1;i<=t;i++){
            scanf("%d%d",&start,&goal);
            memset(vis,0,sizeof(vis));
            int ans=bfs(start,goal);
            if(ans==-1)
                printf("0
    ");
            else
                printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    容器虚拟化之LXC(LinuX Container)
    Twemproxy+Keepalived+Redis
    Haproxy+Keepalived+Nginx
    Redis-sentinel集群
    Server2008r2 指定默认用户自动登录--注册表
    .Net Core应用框架Util介绍(二) 转
    .Net Core应用框架Util介绍(一)转
    一分钟教你知道乐观锁和悲观锁的区别
    设置DataTable行属性
    js中的内置对象
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3364127.html
Copyright © 2011-2022 走看看