题目大意:给定一个4位素数,一个目标4位素数。每次变换一位,保证变换后依然是素数,求变换到目标素数的最小步数。

解题报告:直接用最短路。

枚举1000-10000所有素数,如果素数A交换一位可以得到素数B,则在AB间加入一条长度为1的双向边。

则题中所求的便是从起点到终点的最短路。使用Dijkstra或SPFA皆可。

当然,纯粹的BFS也是可以的。

用Dijkstra算法A了题目之后,看了一下Discuss,发现了一个新名词,双向BFS。

即从起点和终点同时进行BFS,相遇则求得最短路。

借鉴了思想,自己动手实现了代码。原本以为双向比单向快一倍而已,其实远远不止。

笔者用30W数据分别测试了单向和双向。环境为CodeBlock+MinGW4.7,Debug,双向时间为8.618s,而单向为惊人的139.989s!

简单思考了一下,也还是合理的。单向每次的增长是指数级的,而双向的指数只有单向的一半,优化程度相当高。

好了,贴代码~首先是双向BFS的Dijkstra:

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std; const int maxn=;
int prime[maxn];
const int maxV=;
int first[maxV],vv[maxV*maxV],nxt[maxV*maxV];
int num[maxV];
bool vis[][maxV];
int index; bool check(int a,int b)
{
int k=a-b;
if(k%==)
return true;
if(k< && k%== && a/==b/)
return true;
if(k< && k%== && a/==b/)
return true;
if(a/==b/)
return true;
return false;
} void calPrime()
{
for(int i=;i<maxn;i++) if(!prime[i])
{
for(int j=*i;j<maxn;j+=i)
prime[j]=true;
if(i>= && i<)
{
num[++index]=i;
prime[i]=index;
}
} int e=;
memset(first,,sizeof(first));
for(int i=;i<=index;i++)
for(int j=i+;j<=index;j++) if(check(num[j],num[i]))
{
nxt[e]=first[i],vv[e]=j,first[i]=e++;
nxt[e]=first[j],vv[e]=i,first[j]=e++;
}
} struct Node
{
int node;
int level;
bool operator<(const Node& cmp) const
{
return level>cmp.level;
}
} p,q; int Dijkstra(int sta,int end)
{
if(sta==end)
return ; memset(vis,,sizeof(vis)); sta=prime[sta];
end=prime[end]; priority_queue<Node> pq[];
p.node=sta;
p.level=;
vis[][p.node]=true;
pq[].push(p); p.node=end;
p.level=;
vis[][p.node]=true;
pq[].push(p); for(int i=; !pq[].empty() && !pq[].empty() ;i++)
{
int sel=;
if(pq[].size()>pq[].size())
sel++;
int level=pq[sel].top().level;
while(!pq[sel].empty())
{
p=pq[sel].top();
if(p.level!=level) //先判断,否则会pop掉丢失情况
break;
pq[sel].pop(); for(int e=first[p.node];e;e=nxt[e])
{
if(vis[-sel][vv[e]])
return i+;
if(!vis[sel][vv[e]])
{
q.level=p.level+;
q.node=vv[e];
vis[sel][vv[e]]=true;
pq[sel].push(q);
}
}
}
} return -;
} int main()
{
calPrime(); int T;
scanf("%d",&T);
while(T--)
{
int sta,end;
scanf("%d%d",&sta,&end);
int ans=Dijkstra(sta,end);
if(ans==-)
printf("Impossible\n");
else
printf("%d\n",ans);
}
}

然后是单向的BFS+Dijkstra:

#include <cstdio>
#include <cstring>
#include <queue>
using namespace std; const int maxn=;
int prime[maxn];
const int maxV=;
int first[maxV],vv[maxV*maxV],nxt[maxV*maxV];
int num[maxV];
bool vis[maxV];
int index;
int count; bool check(int a,int b)
{
int k=a-b;
if(k%==)
return true;
if(k< && k%== && a/==b/)
return true;
if(k< && k%== && a/==b/)
return true;
if(a/==b/)
return true;
return false;
} void calPrime()
{
for(int i=;i<maxn;i++) if(!prime[i])
{
for(int j=*i;j<maxn;j+=i)
prime[j]=true;
if(i>= && i<)
{
num[++index]=i;
prime[i]=index;
}
} int e=;
memset(first,,sizeof(first));
for(int i=;i<=index;i++)
for(int j=i+;j<=index;j++) if(check(num[j],num[i]))
{
nxt[e]=first[i],vv[e]=j,first[i]=e++;
nxt[e]=first[j],vv[e]=i,first[j]=e++;
}
} struct Node
{
int k;
int w;
bool operator<(const Node& cmp) const
{
return w>cmp.w;
}
} p,q; int Dijkstra(int sta,int end)
{
memset(vis,,sizeof(vis));
end=prime[end]; p.k=prime[sta];
p.w=;
vis[p.k]=true; priority_queue<Node> pq;
pq.push(p); while(!pq.empty())
{
p=pq.top();
pq.pop(); if(p.k==end)
return p.w; for(int e=first[p.k];e;e=nxt[e]) if(!vis[vv[e]])
{
q.k=vv[e];
q.w=p.w+;
vis[q.k]=true;
pq.push(q);
}
}
return -;
} int main()
{
calPrime(); int T;
scanf("%d",&T);
while(T--)
{
int sta,end;
scanf("%d%d",&sta,&end);
int ans=Dijkstra(sta,end);
if(ans==-)
printf("Impossible\n");
else
printf("%d\n",ans);
}
}

测试数据我放在了百度云,有兴趣可以下载下来试一下:http://pan.baidu.com/share/link?shareid=4217669741&uk=2804348991

POJ 3126 Prime Path 解题报告(BFS & 双向BFS)的更多相关文章

  1. 双向广搜 POJ 3126 Prime Path

      POJ 3126  Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16204   Accepted ...

  2. BFS POJ 3126 Prime Path

    题目传送门 /* 题意:从一个数到另外一个数,每次改变一个数字,且每次是素数 BFS:先预处理1000到9999的素数,简单BFS一下.我没输出Impossible都AC,数据有点弱 */ /**** ...

  3. POJ 3126 Prime Path(素数路径)

    POJ 3126 Prime Path(素数路径) Time Limit: 1000MS    Memory Limit: 65536K Description - 题目描述 The minister ...

  4. poj 3126 Prime Path bfs

    题目链接:http://poj.org/problem?id=3126 Prime Path Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  5. POJ - 3126 - Prime Path(BFS)

    Prime Path POJ - 3126 题意: 给出两个四位素数 a , b.然后从a开始,每次可以改变四位中的一位数字,变成 c,c 可以接着变,直到变成b为止.要求 c 必须是素数.求变换次数 ...

  6. POJ 3126 Prime Path 素数筛,bfs

    题目: http://poj.org/problem?id=3126 困得不行了,没想到敲完一遍直接就A了,16ms,debug环节都没进行.人品啊. #include <stdio.h> ...

  7. POJ 3126 Prime Path(BFS 数字处理)

    意甲冠军  给你两个4位质数a, b  每次你可以改变a个位数,但仍然需要素数的变化  乞讨a有多少次的能力,至少修改成b 基础的bfs  注意数的处理即可了  出队一个数  然后入队全部能够由这个素 ...

  8. (简单) POJ 3126 Prime Path,BFS。

    Description The ministers of the cabinet were quite upset by the message from the Chief of Security ...

  9. POJ 3126 Prime Path【从一个素数变为另一个素数的最少步数/BFS】

    Prime Path Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26475 Accepted: 14555 Descript ...

随机推荐

  1. KMP的模版实现(以hdu1711为例)

    贴代码,觉得带template的有一些大材小用……不过还是按自己风格写吧! /************************************************************* ...

  2. TCP传输小数据包效率问题(译自MSDN)

    TCP传输小数据包效率问题(译自MSDN) http://www.ftpff.com/blog/?q=node/16 摘要:当使用TCP传输小型数据包时,程序的设计是相当重要的.如果在设计方案中不对T ...

  3. vc实现ping

    //ping.h #ifndef _CPING_H_ #define _CPING_H_ #include <Winsock2.h> #include <Windows.h> ...

  4. 云盾正常扫描云服务器的IP是什么

    问题:云盾正常扫描云服务器的IP是什么?   解答:云盾扫描云服务器的的IP段固定为    42.120.145.0/24 110.75.105.0/24 110.75.185.0/24 110.75 ...

  5. RX学习笔记:Bootstrap

    Bootstrap https://getbootstrap.com 2016-07-01 在学习FreeCodeCamp课程中了解到Bootstrap,并于课程第一个实战题卡在响应式部分,于是先对B ...

  6. Cassandra1.2文档学习(6)—— 客户端数据请求

    参考文档:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/architecture/a ...

  7. 在jsp中运用ajax实现同一界面不跳转处理事件

    目前,编写应用程序时有两种基本的选择: 桌面应用程序 Web应用程序 它们有什么区别呢?桌面应用程序一般很快(就在您的计算机上运行,不用等待互联网连接),具有漂亮的用户界面(通常和操作系统有关)和非凡 ...

  8. 一步步学习ASP.NET MVC3 (1)——基础知识

    请注明转载地址:http://www.cnblogs.com/arhat 首先在这里我想声明一下,这个ASP.NET MVC3系列是我在授课过程中的一些经验,有什么不对的地方,请大家指出,我们共同的学 ...

  9. sencha touch json store

    js: Ext.define('MyApp.store.MyJsonStore', { extend: 'Ext.data.Store', requires: [ 'MyApp.model.Perso ...

  10. 我的PHP之旅--SQL语句

    SQL语句 结构化查询语言(Structured Query Language)简称SQL,是一种操作数据的语言. 增加记录 INSERT INTO table_name(字段1, 字段2, 字段3) ...