POJ 3126

问最短路径,所以上来就可以考虑BFS

繁杂的部分在具体问题实现细节,借助这道题正好顺手学了线性求素数筛子,模板如下:

for (int i= 2; i<= maxl; ++i){
	if (!chk[i]){
		prime[tot++]= i;
	}
	for (int j= 0; j< tot; ++j){
		int n_p= i*prime[j];
		if (n_p> maxl){
			break;
		}
		chk[n_p]= 1;
		if (!(i%prime[j])){
			break;
		}
	}
}

欧拉筛法核心思想就是每个数一定让他的最小素因数筛去

本体代码核心思路就是素数的预处理,以及预先在4位数素数之间建立图关系

#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <map>
#include <set>
using namespace std;

const int maxn= 1e4+3;
const int maxp= 1100;

int chk[maxn], prime[maxn];
bool vis[maxp];
int dis[maxp];
int tot= 0, head= 0;
vector<int> G[maxp];

void PrimeInit()
{
	memset(chk, 0, sizeof(chk));
	for (int i= 2; i< maxn; ++i){
		if (!chk[i]){
			prime[tot]= i;
			chk[i]= tot++;
		}

		for (int j= 0; j< tot; ++j){
			int n_p= i*prime[j];
			if (n_p>= maxn){
				break;
			}
			chk[n_p]= -1;
			if (!(i%prime[j])){
				break;
			}
		}
	}
	for (int i= 0; i< tot; ++i){
		if (prime[i]> 1000){
			head= i;
			break;
		}
	}

	int b[4];
	int p, dp;
	for (int i= head; i< tot; ++i){
		p= prime[i];
		b[0]= p%10;
		p= p/10;
		b[1]= p%10;
		p= p/10;
		b[2]= p%10;
		p= p/10;
		b[3]= p;

		for (int j= 0; j< 4; ++j){
			int uk= 9-b[j];
			for (int k= 1; k<= uk; ++k){
				dp= k;
				for (int q= 1; q<= j; ++q){
					dp*= 10;
				}
				p= prime[i]+dp;
				if (-1!= chk[p]){
					G[i-head].push_back(chk[p]);
					G[chk[p]-head].push_back(i);
				}
			}
		}
	}
}
int BFS(const int f, const int t)
{
	if (f== t){
		return 0;
	}
	int id;
	memset(vis, 0, sizeof(vis));
	id= chk[f]-head;
	vis[id]= 1;
	dis[id]= 0;
	queue<int> Q;
	Q.push(id);

	while (!Q.empty()){
		id= Q.front();
		Q.pop();
		int sz= G[id].size();
		int v= dis[id]+1;

		for (int i= 0; i< sz; ++i){
			int p_id= G[id][i];
			if (t== prime[p_id]){
				return v;
			}
			p_id-= head;
			if (!vis[p_id]){
				vis[p_id]= 1;
				dis[p_id]= v;
				Q.push(p_id);
			}
		}
	}

	return -1;
}

int main()
{
	int kase, f, t, ans;
	scanf("%d", &kase);

	PrimeInit();
	while (kase--){
		scanf("%d %d", &f, &t);
		ans= BFS(f, t);
		if (-1== ans){
			printf("Impossible\n");
		}
		else {
			printf("%d\n", ans);
		}
	}

	return 0;
}
posted @ 2021-04-20 22:23  IdiotNe  阅读(32)  评论(0编辑  收藏  举报