POJ 3162 Prime Path 题解

7 篇文章 0 订阅
2 篇文章 0 订阅

题目通道

题解

1、离线处理素数表,bool ispri[N]
2、bfs处理。队列操作。

注意细节

多输入的情况下,需要把队列变成空队列。

写法一

#include<iostream>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<map>
#include<vector>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<stack>
#include<ctime>
using namespace std; 
#define rep(i,aa,bb) for(register int i=aa;i<=bb;i++)
#define rrep(i,aa,bb) for(register int i=aa;i>=bb;i--)
#define LL long long 
#define eps 0.000001
#define inf 0x3f3f3f3f
#define exp 0.000001
#define pai 3.141592654
#define random(x)   rand()%(x)
#define lowbit(x)   x&(-x)
inline int read()
{
	int x=0,y=1;char a=getchar();while ( a>'9' || a<'0'){if ( a=='-')y=-1;a=getchar();}
	while ( a>='0' && a<='9' ){	x=10*x+a-'0'; a=getchar();}return x*y;
}
#define N 10005
bool ispri[N];
int pri[N];int tot = 0; 
void getpri(int n){
	ispri[1] = 1; 
	memset(ispri,1,sizeof(ispri));
	for ( int i = 2; i <= n; i++){
		if ( ispri[i] == 1 )	pri[++tot] = i; 
		for (int j = 1; j <= tot && i*pri[j] <= n ; j++){
			ispri[ i*pri[j] ] = 0 ;
			if ( i % pri[j] == 0 )	break;  
		}
	}
}
struct node {
	int step,sta; 
};
queue<node>q; 
bool vis[N];int st,ed,t; 
int bit[9],basebit[9];
void getbit(int temnum){
	int temlen = 0; 
	while ( temnum ){
		bit[++temlen] = temnum%10; 
		temnum /= 10;  
	}
}
int getback(){
	int temnum; 
	temnum = bit[1] + bit[2]*10 + bit[3]*100 + bit[4]*1000;
	return temnum; 
}
void bfs(){
	while ( q.empty() == 0 ){
		node now,nex; 
		now = q.front();
		q.pop();
		if ( now.sta == ed ){
			printf("%d\n",now.step);
			return ; 
		}
		getbit(now.sta);
		memcpy(basebit,bit,sizeof(bit));
		rep(i,1,4){
			int temstar; 
			if ( i == 4 )	temstar = 1; 
			else 			temstar = 0; 
			
			memcpy(bit,basebit,sizeof(bit));
			
			rep(j,temstar,9){
				bit[i] = j; 
				nex.sta = getback(); 
				nex.step = now.step + 1;
				if ( vis[nex.sta] == 0 && ispri[nex.sta]){
					vis[nex.sta] = 1; 
					q.push(nex);
				} 
			}
		}
	}
}
int main()
{
//	freopen("1.txt","r",stdin);
	srand((int)time(0));
	std::ios::sync_with_stdio(false);
	int n = 10000;
	memset(ispri,0,sizeof(ispri));
	getpri(n);

	t = read();
	rep(aiiiiiii,1,t){
		st = read();
		ed = read();
		node a ; 
		while (q.empty() == 0 ) 	q.pop(); 
		a.step = 0 ; a.sta = st;
		q.push(a);
		memset(vis,0,sizeof(vis));
		vis[st] = 1 ;
		bfs();
	}
	return 0;
}

写法二

#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#include<cstdio>
#include<ctime>
#include<queue>
#include<cmath>
#include<algorithm>
using namespace std; 
const int N = 10003;
bool ispri[N];int prime[N];int cnt=0;
bool vis[ N ]={0};
int a,b;
inline void getpri(int n)
{
	memset (ispri,1,sizeof(ispri));
	memset (prime,0,sizeof(prime));
	ispri[1] = 0;
	for ( int i = 2; i <= n; i++)
	{
		if( ispri[ i ])		
			prime[++cnt] = i; 
		for ( int j = 1; j <= cnt && prime[j]*i <= n; j++)
		{
			ispri[ i*prime[j] ] = 0; 
			if ( i%prime[j]==0 ) break; 
		}
	} 
}
//void getpri(int n){
//	int ok = 1;
//	ispri[1] = 0;  
//	for ( int i = 2; i <= n; i++)
//	{
//		ok=1;
//		for (int j = 2; j <= int ( sqrt(i)+0.5 ) ; j++)
//			if ( i%j ==  0 )
//				ok = 0; 
//		ispri[i] = ok; 		 
//	}
//}
struct Node{
	int sta,dep;
};
queue< Node >q; 
void print(){
	while ( !q.empty () ){
		Node a=q.front() ; 
		printf("%5d\t%4d\n",a.sta,a.dep);
		q.pop(); 
	}
}
void solve(){
	while ( !q.empty() ){
		Node tmp = q.front() ; q.pop() ; 
		Node now; 
		if ( tmp.sta == b ){
			printf("%d\n",tmp.dep);
			return ;
		}
		int sta;
		
		for (int i = 1; i <= 9; i+=2)
		{
			int sta = tmp.sta/10*10 + i; 
			if ( sta != tmp.sta && ispri[sta] && !vis[sta]){
				now.sta = sta; now.dep = tmp.dep+1; 
				q.push( now); 	
				vis[ sta ] = 1; 
			}
		}
		for (int i = 0; i <= 9; i++)
		{
			int sta = tmp.sta/100*100 + i*10 + tmp.sta % 10; 
			if ( sta != tmp.sta && ispri[sta] && !vis[sta]){
				now.sta = sta; now.dep = tmp.dep+1; 
				q.push( now); 		
				vis[ sta ] = 1; 
			}
		}
		for (int i = 0; i <= 9; i++)
		{
			int sta = tmp.sta/1000*1000 + i*100 + tmp.sta % 100; 
			if ( sta != tmp.sta && ispri[sta] && !vis[sta]){
				now.sta = sta; now.dep = tmp.dep+1; 
				q.push( now); 		
				vis[ sta ] = 1; 
			}
		}	
		for (int i = 1; i <= 9; i++)
		{
			int sta = tmp.sta % 1000 + i*1000; 
			if ( sta != tmp.sta && ispri[sta] && !vis[sta]){
				now.sta = sta; now.dep = tmp.dep+1; 
				q.push( now); 		
				vis[ sta ] = 1; 
			}
		}				
//		print();
	}
	return ; 
}
int main()
{
//	freopen("1.txt","r",stdin);
//	clock_t a;		a=clock();
	getpri(10000);
//	clock_t b;		b=clock();	
//	printf("%d",b-a);
//	for (int i = 1;i <= 10000; i++)
//		if ( ispri[i] )	printf("%d\t",i);
	int n; scanf("%d",&n);
	while ( n-- ){
		scanf("%d%d",&a,&b);
		memset(vis,0,sizeof(vis));
		vis[ a ] = 1 ; 
		while ( !q.empty() )	q.pop() ;
		Node now;now.sta = a; now.dep = 0; 
		q.push( now ); 
		solve();
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值