zoukankan      html  css  js  c++  java
  • BFS --- 素数环

    <传送门>

    【题目大意】
    对话很坑爹,不过很有意思,直接看题干就可以了。
    给你两个四位数a和b,现在要你从a经过变换得到b,并且变换的中间的每一位都要是素数,并且相邻两个素数之间只能有一个位不同。
    【题目分析】
    开始没想到怎么做,以为有什么高深的解法,后来经大神指点说是爆搜就可,思路才打开。

    这题没什么陷阱,用爆搜时间复杂度也很低。

    怎么爆搜呢?
    我们将a的每个位都从0~9列举出来放入队列中,其实就是BFS,只不过是40出口的BFS,但是个位上必须将偶数除掉,顿时就少了一半的搜索量。

    因为数据不是很大,所以我们可以用结构体数组来模拟队列。
    BFS队列+素数判定

    //Memory   Time
    //  256K       32MS
    #include<iostream>
    #include<cstring>
    using namespace std;
    
    struct Node
    {
            int prime;
            int step;
    };
    
    bool JudgePrime(int digit)
    {
        if(digit==2 || digit==3)
            return true;
        else if(digit<=1 || digit%2==0)
            return false;
        else if(digit>3)
        {
            for(int i=3;i*i<=digit;i+=2)
                if(digit%i==0)
                    return false;
            return true;
        }
    }
    
    int a,b;
    bool vist[15000];
    Node queue[15000];
    
    void BFS(void)
    {
        int i;  //temporary
        int head,tail;
        head=tail=0;
        queue[head].prime=a;
        queue[tail++].step=0;
        vist[a]=true;
    
        while(head<tail)
        {
            Node x=queue[head++];//出队
            if(x.prime==b)
            {
                cout<<x.step<<endl;
                return;
            }
    
            int unit=x.prime%10;      
            int deca=(x.prime/10)%10;  
            for(i=1;i<=9;i+=2)    
            {
                int y=(x.prime/10)*10+i;
                if(y!=x.prime && !vist[y] && JudgePrime(y))
                {
                    vist[y]=true;
                    queue[tail].prime=y;
                    queue[tail++].step=x.step+1;
                }
            }
            for(i=0;i<=9;i++)     
            {
                int y=(x.prime/100)*100+i*10+unit;
                if(y!=x.prime && !vist[y] && JudgePrime(y))
                {
                    vist[y]=true;
                    queue[tail].prime=y;
                    queue[tail++].step=x.step+1;
                }
            }
            for(i=0;i<=9;i++)   
            {
                int y=(x.prime/1000)*1000+i*100+deca*10+unit;
                if(y!=x.prime && !vist[y] && JudgePrime(y))
                {
                    vist[y]=true;
                    queue[tail].prime=y;
                    queue[tail++].step=x.step+1;
                }
            }
            for(i=1;i<=9;i++)    
            {
                int y=x.prime%1000+i*1000;
                if(y!=x.prime && !vist[y] && JudgePrime(y))
                {
                    vist[y]=true;
                    queue[tail].prime=y;
                    queue[tail++].step=x.step+1;
                }
            }
        }
    
        cout<<"Impossible"<<endl;
        return;
    }
    
    int main(void)
    {
        int test;
        cin>>test;
        while(test--)
        {
            cin>>a>>b;
            memset(vist,false,sizeof(vist));
            BFS();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Hdu 5396 Expression (区间Dp)
    Lightoj 1174
    codeforces 570 D. Tree Requests (dfs)
    codeforces 570 E. Pig and Palindromes (DP)
    Hdu 5385 The path
    Hdu 5384 Danganronpa (AC自动机模板)
    Hdu 5372 Segment Game (树状数组)
    Hdu 5379 Mahjong tree (dfs + 组合数)
    Hdu 5371 Hotaru's problem (manacher+枚举)
    Face The Right Way---hdu3276(开关问题)
  • 原文地址:https://www.cnblogs.com/crazyacking/p/3762950.html
Copyright © 2011-2022 走看看