Prime Path POJ - 3126 BFS

很久没更新博客了 随便记录一道水题吧

题意略,做法很简单,把他看做在四维空间中求最短路,只不过“行走”的规则是某一象限的值变为任意的值 用个四维数组就行 建议一开始用欧拉筛筛下素数。

做的有点久 不小心把isprime数组写成prime ORZ

AC代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <bitset>
#include <vector>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
const int maxn=15;
const int pmaxn=10005;
int a[maxn][maxn][maxn][maxn];
int vis[maxn][maxn][maxn][maxn];
int num[maxn][maxn][maxn][maxn];
int go[maxn][maxn][maxn][maxn];
int prime[pmaxn],primesize,phi[pmaxn];
bool isprime[pmaxn];
struct point
{
    int x,y,z,k;
}in,out;
queue<point>q;
void getlist(int listsize)
{
    primesize=0;
    memset(isprime,1,sizeof(isprime));
    isprime[1]=false;
    for(int i=2;i<=listsize;i++)
    {
        if(isprime[i]) prime[++primesize]=i;
        for(int j=1;j<=primesize&&i*prime[j]<=listsize;j++)
        {
            isprime[i*prime[j]]=false;
            if(i%prime[j]==0) break;
        }
    }
}
bool judge(point temp)
{
    int x=temp.x,y=temp.y,z=temp.z,k=temp.k;
    int val=x*1000+y*100+z*10+k;
    //if(val==1733) cout<<isprime[val]<<" uiu "<<endl;
    //if(val==1733) cout<<vis[x][y][z][k]<<" pkpb "<<endl;
    if(vis[x][y][z][k]) return false;
    if(!isprime[val]) return false;
    return true;
}
void bfs()
{
    q.push(in);
    while(!q.empty())
    {
        point v=q.front();
        int ans=num[v.x][v.y][v.z][v.k];
        vis[v.x][v.y][v.z][v.k]=1;
        q.pop();
        for(int i=0;i<4;i++)
        {
            for(int j=i?0:1;j<=9;j++)
            {
                if(i==0)
                {
                    point temp=v;
                    temp.x=j;
                    if(judge(temp))
                    {
                        vis[j][v.y][v.z][v.k]=1;
                        num[j][v.y][v.z][v.k]=ans+1;
                        q.push(temp);
                    }
                }
                else if(i==1)
                {
                    point temp=v;
                    temp.y=j;
                    if(judge(temp))
                    {
                        vis[v.x][j][v.z][v.k]=1;
                        num[v.x][j][v.z][v.k]=ans+1;
                        q.push(temp);
                    }
                }
                else if(i==2)
                {
                    point temp=v;
                    temp.z=j;
                    if(judge(temp))
                    {
                        vis[v.x][v.y][j][v.k]=1;
                        num[v.x][v.y][j][v.k]=ans+1;
                        q.push(temp);
                    }
                }
                else if(i==3)
                {
                    point temp=v;
                    temp.k=j;
                    if(judge(temp))
                    {
                        vis[v.x][v.y][v.z][j]=1;
                        num[v.x][v.y][v.z][j]=ans+1;
                        q.push(temp);
                    }
                }
            }
        }
    }
}
int main()
{
    getlist(10000);
    int t;cin>>t;
    while(t--)
    {
        memset(a,0,sizeof(a));
        memset(vis,0,sizeof(vis));
        memset(num,0,sizeof(num));
        while(!q.empty()) q.pop();
        string n,m;
        cin>>n>>m;
        in.x=n[0]-'0',in.y=n[1]-'0',in.z=n[2]-'0',in.k=n[3]-'0';
        out.x=m[0]-'0',out.y=m[1]-'0',out.z=m[2]-'0',out.k=m[3]-'0';
        bfs();
        printf("%d\n",num[out.x][out.y][out.z][out.k]);
    }
}
/*
3
1033 8179
1373 8017
1033 1033
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值