【BFS】hdu 1973 Prime Path

题目描述:

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

 

中文大意:

有钱人更换门牌号码。

门牌号码有 4 位,且必须为质数。

更换一个数字的成本是 1 磅,每次只能更换一个数字。

要求:计算更换成目标门牌号码的最小花费。

 

思路:

队列节点记录的是当前门牌号和当前的花费。

弹出队列首节点,确定了当前门牌信息后,下一步有 9 + 3 x 10 种选择,注意要考虑“首位不能为 0 ”这种情况。

其中,“素数判断”的方法必须优化,最好事先打表,不然会超时。

 

代码:

#include<bits/stdc++.h>
using namespace std;

struct node{
    string str;
    int cost;
};

bool visited[10000];

bool prime[10000] = {false};

string str1,str2;

//判断一个数是否是素数 
bool is_prime(string str){
    int val = 0;
    for(int i=0;i<4;i++){
        val *= 10;
        val += str[i] - '0';
    }
    
    if(prime[val] == true){
        return true;
    }
    else{
        return false;
    }
}

//判断一个数是否已经被访问 
bool is_visited(string str){
    int val = 0;
    for(int i=0;i<4;i++){
        val *= 10;
        val += str[i] - '0';
    }
    
    if(visited[val] == false){
        visited[val] = true;
        return false;
    }
    else{
        return true;
    }
} 

int bfs(){
    node start,next;
    start.str = str1;
    start.cost = 0;
    
    is_visited(start.str);
    
    queue<node> q;
    q.push(start);
    
    while(!q.empty()){
        start = q.front();
        q.pop();
        
        if(start.str == str2){
            return start.cost;
        }
        
        for(int i=0;i<4;i++){
            for(int j=0;j<=9;j++){
                //首位不能为0 
                if(i == 0 && j == 0){
                    continue;
                }
                
                next.str = start.str;
                next.str[i] = j + '0';
                
                next.cost = start.cost + 1;
                
                if(is_prime(next.str) && !is_visited(next.str)){
                    q.push(next);
                }
            }
        }
    }
    return -1; 
}

int main(){
    //计算1000~9999范围内的素数 
    for(int val=1000;val<=9999;val++){
        bool flag = true;
        int k = int(sqrt(val));
        
        for(int i=2;i<=k;i++){
            if(val % i == 0){
                flag = false;
                break;
            }
        }
        
        if(flag){
            prime[val] = true;
        }
    }

    int n;
    scanf("%d", &n);
    while(n--){
        cin>>str1>>str2;
        
        memset(visited, false, sizeof(visited));
        
        int cost = bfs();
        if(cost < 0){
            printf("Impossible
");
        }
        else{
            printf("%d
", cost);
        }
    }
} 
作者:老干妈就泡面
本文版权归作者和博客园共有,欢迎转载,但请给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/bjxqmy/p/14363683.html