Prime Path(用queue写广搜)

本文介绍了一种算法问题,如何通过最少的步骤将一个四位素数变换为另一个,每次变换只允许改变一位数字,且新的数字必须构成另一个四位素数。博主展示了使用广度优先搜索解决此问题的方法,并给出了具体样例和代码实现。

题目:

给你两个四位的素数 a,ba,b 。
 aa 可以改变某一位上的数字变成 cc ,但只有当 cc 也是四位的素数时才能进行这种改变。
请你计算 aa 最少经过多少次上述变换才能变成 bb 。
例如:1033 -> 8179 
1033 
1733 
3733 
3739 
3779 
8779 
8179
最少变换了6次。

输入格式

第一行输入整数 TT ,表示样例数。 (T \le 100)(T≤100)
每个样例输入两个四位的素数 a, ba,b 。(没有前导零) 

输出格式

对于每个样例,输出最少变换次数,如果无法变换成 bb 则输出"Impossible"。

注意:仅对于此题,输出时每行末尾的多余空格,不影响答案正确性。

输入样例

3
1033 8179
1373 8017
1033 1033

输出样例

6
7
0

这道题相当于广搜的四个方向,即把四位数的每个数位走一遍,先把四位的素数打个表再写

代码:

#include<stdio.h>
#include<string.h>
#include<queue>
#define N 10100
using namespace std;
int n,st,en;
bool book[N];
bool ss[N];
struct node {
	int step;
	int num;
};
void init() // 素数打表 
{
	for(int i=2; i<10000; i++) {
		if(ss[i])continue;
		for(int j=i+i; j<10000; j+=i) {
			ss[j]=true;
		}
	}
}
void bfs() 
{
	memset(book,0,sizeof(book));
	queue<node>q;
	node x;
	//存开始的那个数即为“起点” 
	x.num=st;
	x.step=0;//此时步数即变换次数为0 
	book[x.num]=true;//标记已经走过 
	q.push(x);//存入队列 
	while(!q.empty()) 
	{
		//把队列中的元素提出来并清除 
		node x=q.front();
		q.pop();
		if(x.num==en) //如果已经找到或着说到达要变幻的素数就输出此时步数 
		{
			printf("%d\n",x.step);
			return ;
		}
		for(int i=0; i<4; i++) //四位数每个数位都要从1到9走一遍 
		{
			for(int j=0; j<10; j++) 
			{
				if(!i&&!j)
					continue;
				node y;//y为x的下一步 
				y.step=x.step+1;
				
				int a=x.num/1000;
				int b=x.num%1000/100;
				int c=x.num%100/10;
				int d=x.num%10;
				if(i==0)
					a=j;
				else if(i==1)
					b=j;
				else if(i==2)
					c=j;
				else if(i==3)
					d=j;
				y.num=a*1000+b*100+c*10+d;
				//判断y这个数是不是素数 
				if(book[y.num]||ss[y.num])
					continue;
				book[y.num]=true;//标记走过 
				q.push(y);//存入队列方便下一次取出 
			}
		}
	}
}
int main() {
	init();
	scanf("%d",&n);
	while(n--) {
		scanf("%d%d",&st,&en);
		bfs();
	}
	return 0;
}

### 关于素数算法及其应用 #### 素数的概念与性质 素数是指除了1和它本身外无法被其他自然数整除的大于1的正整数。对于给定的一个整数 \(n\),判断其是否为素数可以通过试除法实现,即尝试从2到\(\sqrt{n}\)之间的所有整数来验证是否存在能整除\(n\)的情况[^1]。 #### 最大质因数位置问题解析 针对题目描述中的最大质因数的位置求解问题,核心在于两个方面:一是如何高效找到一个数的所有质因子;二是确定这些质因子中最大的那个对应的序列号。具体方法如下: - **埃拉托斯特尼筛法(Sieve of Eratosthenes)** 可用于预先计算一定范围内所有的素数列表。通过构建布尔数组标记哪些索引代表的是素数,在后续查询过程中能够快速定位任意数值的最大质因数。 ```cpp bool sieve[1000001]; void initSieve(){ memset(sieve, true, sizeof(sieve)); sieve[0] = sieve[1] = false; for(long long p=2;p*p<=1e6;p++) if(sieve[p]) for(long long multiple=p*p;multiple<=1e6;multiple+=p) sieve[multiple] = false; } ``` - 对于输入数据集内的每一个整数\(n\),利用上述筛选结果逐步分解得到它的全部质因素,并记录其中具有最高序位者作为最终答案输出[^2]。 #### 数字转换路径上的素数约束条件分析 当涉及由初始状态向目标状态转变的过程中始终保持中间态皆满足特定属性——此处特指保持每一步均为素数的要求时,可采用广度优先(BFS)策略探索最短合法变换链路[^3]。 ```python from collections import deque def bfs_prime_path(start, end): visited = set() queue = deque([(start, "")]) while queue: current_num, path_str = queue.popleft() if current_num == end: return path_str str_current = f"{current_num:04}" for idx in range(4): for digit_char in '0123456789': temp_list = list(str_current) temp_list[idx] = digit_char candidate = int(''.join(temp_list)) if checkPrime(candidate) and candidate not in visited and 1000 <= candidate < 10000: visited.add(candidate) queue.append((candidate, path_str + "->" + str(candidate))) return "No solution" ``` 这里`checkPrime()`函数需另行定义完成基本素性检测功能。 #### 非素数因子计数优化方案探讨 有鉴于某些场景下需要统计某指定区间内各元素所含非素数类别的数量总和情况,借助辅助结构提前做好充分准备显得尤为重要。下面展示了一种基于动态规划思想的设计思路实例[^4]: ```c++ #include<bits/stdc++.h> using namespace std; const int MAX_N=2*1e6+10; int vis[MAX_N], cnt_non_primes[MAX_N]; void preprocess(){ fill(vis,vis+MAX_N,0); for(int i=2;i<MAX_N;i++){ if(!vis[i]){ for(int j=i+i;j<MAX_N;j+=i){ vis[j]++; } } } for(int k=2;k<MAX_N;k++) { if(vis[k]) cnt_non_primes[k]=cnt_non_primes[k-1]+1; else cnt_non_primes[k]=cnt_non_primes[k-1]; } } // 查询部分省略... ``` 此代码片段展示了如何有效预处理并累积存储有关非素数的信息以便即时响应各类询问需求。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值