CSU 1090: Number Transformation 一个非常好的优先队列打表

1090: Number Transformation

Time Limit: 1 Sec   Memory Limit: 128 MB
SUBMIT: 375   Solved: 41
[SUBMIT] [STATUS]

Description

 In this problem, you are given a pair of integers A and B. You can transform any integer number A to B by adding x to A.This x is an integer number which is a prime below A.Now,your task is to find the minimum number of transformation required to transform S to another integer number T.

Input

 Input contains multiple test cases.Each test case contains a pair of integers S and T(0< S < T <= 1000) , one pair of integers per line. 

Output

 For each pair of input integers S and T you should output the minimum number of transformation needed as Sample output in one line. If it's impossible ,then print 'No path!' without the quotes.

Sample Input

5 7
3 4

Sample Output

Need 1 step(s)
No path!

HINT

/*题意 输入2个数 a,b  给a加上一个比a小的素数 使得a等于b  问 最少需要多少步才能从a转化到b
如果不可能转化到b  则输出 No path! 
思路:  暴力必死  一开始我想用背包搞 搞不出来    后来用背包判断是否存在 如果存在再去暴力
依旧超时   后来参考了大神的代码 终于恍悟 用优先队列去打表  从1到1000 分别做起始点 用优先
队列 去找出到达比a大的点的最小步骤 优先队列用在这里漂亮极了  表打出来后 直接对应输出即可*/

/*注意:A的素数范围是动态增加的 这个地方很坑爹 题意没有描述清楚 即a变向b的过程 a增大那么a的素数也增多*/
/*这个题很容易超时  而且数据不是很大  这时候我们应该条件反射的想起来打表 因为他的数据不大
但是还是超时 说明一组数据 他可能重复出现了好几次 再数据中  所以这时候打表很有效
打表分两种
1: 打进文件  然后复制到程序中  这个要求 表的长度不是很大 oj提交 会限制代码长度
2: 赋值给程序中的数组 输入数据后 直接调用*/
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<queue>
using namespace std;
int prime[1005],vis[1100],cnt;
int ans[1010][1010];
struct haha
{
 int num;
 int step;
 friend bool operator <(struct haha a,struct haha b)
 {
  return a.step>b.step;
 }
}q,temp;
void get_prime()
{    
 int i,j,n;   
 double m;  
 n=1002;cnt=0; 
 m=sqrt(n+0.5); 
 memset(vis,0,sizeof(vis));   
 for(i=2;i<=m;i++) if(!vis[i])  
 {          
  for(j=i*i;j<=n;j+=i) 
   vis[j]=1;    
 }   
 for(j=2;j<=n;j++)
  if(!vis[j])   
  {       
   prime[cnt++]=j;   
  }
}
void get_ans(int s)
{
 int i,e;
 priority_queue<haha>que;
 q.num=s;
 q.step=0;
 ans[s][s]=0;
 que.push(q);
 while(!que.empty())
 {
         temp=que.top();
   que.pop();
   q.step=temp.step+1;
   for(i=0;i<cnt&&prime[i]<temp.num;i++)///是temp.num 不是s
   {
    e=temp.num+prime[i];
    if(e>1000) continue;
                if(ans[s][e]==-1||q.step<ans[s][e])
    {
     ans[s][e]=q.step;
     q.num=e;
     que.push(q);
    }
   }
 }
}
int main()
{    
 int a,b,i;  
 get_prime();
 memset(ans,-1,sizeof(ans));
 for(i=2;i<=1000;i++)
     get_ans(i);
 while(scanf("%d %d",&a,&b)!=EOF)   
 {       
       
     if(ans[a][b]==-1) printf("No path!\n");
     else printf("Need %d step(s)\n",ans[a][b]);
 }   
 return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值