POJ 3126 Prime Path【素数筛+bfs】

题目

大意:给定两个四位数的素数。每次只能改变一个数字,且改变后的数字也同样是素数,求解是否存在这样的方法。如果存在,那么最少的替换次数是多少?
例如:
1033
1733
3733
3739
3779
8779
8179
总计变化了六次,输出结果为6.

输入

One line with a positive number: the number of test cases (at most 100). Then for each test case, one line with two numbers separated by a blank. Both numbers are four-digit primes (without leading zeros)

输出

One line for each case, either with a number stating the minimal cost or containing the word Impossible.

输入样例

3
1033 8179
1373 8017
1033 1033

输出样例

6
7
0

题目分析

本题主要采用了通过欧拉筛选出四位数中所有的素数,随后利用广度优先搜索的方法对每一种变换均加以追踪枚举。

关于欧拉筛获取素数的代码解说可戳这里

此处主要分析bfs的应用。

代码

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;

class num{
	public:
		int t[5];//保存四位数的每位数字
		int step;//第几次变换
		int sum;//四位数的大小
		void getsum(){
			sum = t[1]*1000+t[2]*100+t[3]*10+t[4];
		}
};

int isprime[10005];//对素数标记
int prime[10005];
int cnt = 0;
void getprime(){//欧拉筛得到10000以内的素数
	memset(isprime,1,sizeof(isprime));
	isprime[1] = 0;
	for(int i = 2;i<10000;++i){
		if(isprime[i]) prime[++cnt]=i;
		for(int j = 1;j<=cnt&&(i*prime[j])<10000;++j){
			isprime[i*prime[j]] = 0;
			if(i%prime[j]==0) break;
		}
	}
}

int bfs(int init,int fin)
{
	if(init == fin) return 0;
	num first,end;
	int vis[10005] = {0};//避免重复,标记已经变换的数
	first.t[1] = init / 1000;
	first.t[2] = init/100%10;
	first.t[3] = (init%100)/10;
	first.t[4] = init%10;
	first.step = 0;
	vis[init] = 1;
	queue<num> qu;
	qu.push(first);
	while(!qu.empty()){
		first = qu.front();
		qu.pop();
		for(int i = 1;i<5;++i){//四个数字依次变换
			for(int j = 1;j<10;++j){
				end = first;
				end.t[i] = (first.t[i]+j)%10;
				if(end.t[1] == 0) continue;//最高位不可为零
				end.getsum();
				if(end.sum == fin)
					return end.step+1;
				else if((isprime[end.sum]!=0)&&(vis[end.sum]!=1)){
					end.step+=1;
					qu.push(end);
					vis[end.sum] = 1;
				}
			}
		}
	}
	return -1;
}

int main()
{
	int init,fin,ans,group;
	getprime();
	cin >> group;
	for(int i = 0;i<group;++i)
	{
		scanf("%d %d",&init,&fin);
		ans = bfs(init,fin);
		if(ans == -1) cout <<"Impossible"<<endl;
		else cout << ans<<endl;
	}
	return 0;
}

运行结果

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在MATLAB中,NURBS(非均匀有理B样条)是一种强大的数学工具,用于表示和处理复杂的曲线和曲面。NURBS在计算机图形学、CAD(计算机辅助设计)、CAM(计算机辅助制造)等领域有着广泛的应用。下面将详细探讨MATLAB中NURBS的绘制方法以及相关知识点。 我们需要理解NURBS的基本概念。NURBS是B样条(B-Spline)的一种扩展,其特殊之处在于引入了权重因子,使得曲线和曲面可以在不均匀的参数空间中进行平滑插值。这种灵活性使得NURBS在处理非均匀数据时尤为有效。 在MATLAB中,可以使用`nurbs`函数创建NURBS对象,它接受控制点、权值、 knot向量等参数。控制点定义了NURBS曲线的基本形状,而knot向量决定了曲线的平滑度和分布。权值则影响曲线通过控制点的方式,大的权值会使曲线更靠近该点。 例如,我们可以使用以下代码创建一个简单的NURBS曲线: ```matlab % 定义控制点 controlPoints = [1 1; 2 2; 3 1; 4 2]; % 定义knot向量 knotVector = [0 0 0 1 1 1]; % 定义权值(默认为1,如果未指定) weights = ones(size(controlPoints,1),1); % 创建NURBS对象 nurbsObj = nurbs(controlPoints, weights, knotVector); ``` 然后,我们可以用`plot`函数来绘制NURBS曲线: ```matlab plot(nurbsObj); grid on; ``` `data_example.mat`可能包含了一个示例的NURBS数据集,其中可能包含了控制点坐标、权值和knot向量。我们可以通过加载这个数据文件来进一步研究NURBS的绘制: ```matlab load('data_example.mat'); % 加载数据 nurbsData = struct2cell(data_example); % 转换为cell数组 % 解析数据 controlPoints = nurbsData{1}; weights = nurbsData{2}; knotVector = nurbsData{3}; % 创建并绘制NURBS曲线 nurbsObj = nurbs(controlPoints, weights, knotVector); plot(nurbsObj); grid on; ``` MATLAB还提供了其他与NURBS相关的函数,如`evalnurbs`用于评估NURBS曲线上的点,`isoparm`用于生成NURBS曲面上的等参线,以及`isocurve`用于在NURBS曲面上提取特定参数值的曲线。这些工具对于分析和操作NURBS对象非常有用。 MATLAB中的NURBS功能允许用户方便地创建、编辑和可视化复杂的曲线和曲面。通过对控制点、knot向量和权值的调整,可以精确地控制NURBS的形状和行为,从而满足各种工程和设计需求。通过深入理解和熟练掌握这些工具,可以在MATLAB环境中实现高效的NURBS建模和分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

registor11

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

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

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

打赏作者

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

抵扣说明:

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

余额充值