POJ 3126-Prime Path

题目描述
发明一种方案,把一个四位数质数变到另一个四位数质数,路径中每次只改变一个数字,每次改变后的四位数也是质数。
一个数字的价格是一磅,找到在两个给定的四位数素数之间最便宜的素数路径,第一位必须为非零。
例如1033->8179的质数路径:
1033->1733->3733->3739->3779->8779->8179
该解决方案的成本为6磅。
请注意,在步骤2中粘贴的数字1不能在最后一步中重复使用-必须购买新的1。

输入
一行带有正数:测试用例的数量(最多100个)。然后,对于每个测试用例,用两个数字用空格分隔的一行。
这两个数字都是四位数的质数(无前导零)。

输出
每种情况只用一行,或者用数字表示最低费用,或包含“Impossible”一词。

样本输入

3
1033 8179
1373 8017
1033 1033

样本输出

6
7
0

题目思路

将初始的四位数拆分成各个位数上的数字a,b,c,d,分别为千位、百位、十位、个位。
据题意可知,千位数不可为0,所以在千位数替换时从 1-9,替换的数字不能为原数字。
其他位数则可以选取 0-9 之间的数字替换。
替换之后,再将各个数字乘位数得到新的四位数检查是否为质数,且必须是之前没有变换到的数(用vis[]数组检查状态)。
如果满足这两个条件则可以入队,花费+1,继续下一次替换直到替换到终态。

代码如下:

#include<queue>
#include<iostream>
#include<cstdio>
#include<cstring>
#define fio ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
struct node {
  int num;
  int ans;
}t1, t2;
int t, start, e, flag;
queue<node> q;
bool vis[10005];
int check(int n) {
  if (n <= 1) return 0;
  for (int i = 2; i*i <= n; i++)
    if (n%i == 0) return 0;
  return 1;
}
void bfs(int start, int e) {
  t1.num = start;
  t1.ans = 0;
  vis[t1.num] = 1;
  q.push(t1);
  while (!q.empty()) {
    t1 = q.front();  
    q.pop();
    int temp,a,b,c,d;
    for (int i = 0; i < 4; i++) {
      d = t1.num%10;c = t1.num/10%10;
      b = t1.num/100%10; a = t1.num/1000;
      if (i == 0) {
        for(int j = 1; j <= 9; j++) {
          if (j != a) {
            temp = j*1000+b*100+c*10+d;
            if (check(temp) && !vis[temp]) {
              t2.num = temp;
              t2.ans = t1.ans+1;
              if (t2.num == e) {
                flag = 1;
                printf("%d\n", t2.ans);
                return;
              }
              vis[t2.num] = 1;
              q.push(t2);
            }
          }
        }
      } 
      if (i == 1) {
        for (int j = 0; j <= 9; j++) {
          if (j != b) {
            temp = a*1000+j*100+c*10+d;
            if (check(temp) && !vis[temp]) {
              t2.num = temp;
              t2.ans = t1.ans+1;
              if (t2.num == e) {
                flag = 1;
                printf("%d\n", t2.ans);
                return;
              }
              vis[t2.num] = 1;
              q.push(t2);
            }
          }
        }
      }
      if (i == 2) {
        for (int j = 0; j <= 9; j++) {
          if (j != c) {
            temp = a*1000+b*100+j*10+d;
            if (check(temp) && !vis[temp]) {
              t2.num = temp;
              t2.ans = t1.ans+1;
              if (t2.num == e) {
                flag = 1;
                printf("%d\n", t2.ans);
                return;
              }
              vis[t2.num] = 1;
              q.push(t2);
            }
          }
        }
      }
      if (i == 3) {
        for (int j = 0; j <= 9; j++) {
          if (j != d) {
            temp = a*1000+b*100+c*10+j;
            if (check(temp) && !vis[temp]) {
              t2.num = temp;
              t2.ans = t1.ans+1;
              if (t2.num == e) {
                flag = 1;
                printf("%d\n", t2.ans);
                return;
              }
              vis[t2.num] = 1;
              q.push(t2);
            }
          }
        }
      }
    }   
  }
} 
int main() {
  scanf("%d", &t);
  while (t--) {
    scanf("%d%d", &start, &e);
    memset(vis, 0, sizeof(vis));
    while (!q.empty()) q.pop();
    if (start == e) {
      printf("0\n");
    } else {
      flag = 0;
      bfs(start, e);
      if (flag == 0) printf("Impossible\n");
    }
  }
}

ac,如果有错误请各位大佬指出~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你脸上有BUG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值