POJ3126 Prime Path 素數

         這題先將10000以內的素數都找出來,然後在滿足條件的每對素數連上一個權爲1的邊,接着用dijkstra計算一下最短路就可以。
#ifndef HEAD
#include <stdio.h>
#include <vector>
#include <math.h>
#include <string.h>
#include <string>
#include <iostream>
#include <queue>
#include <list>
#include <algorithm>
#include <stack>
#include <map>

using namespace std;
#endif // !HEAD

#ifndef QUADMEMSET
inline void QuadMemSet(void* dst, int iSize, int value)
{
	iSize = iSize / 4;
	int* newDst = (int*)dst;
#ifdef WIN32
	__asm
	{
		mov edi, dst
			mov ecx, iSize
			mov eax, value
			rep stosd
	}
#else
	for (int i = 0; i < iSize; i++)
	{
		newDst[i] = value;

	}
#endif
}
#endif

struct EDGE
{
	int from;
	int to;
	int cost;
	EDGE* next;
};

int Dij(int s, int to, vector<EDGE*> &head,int N)
{
	vector<int> visited;
	visited.resize(N, 0);
	vector<int> res;
	res.resize(N, 10000000);
	res[s] = 0;
	//int t = s;
	while (true)
	{
		int v = -1;
		for (int t = 0; t<N; t++)
		{
			if (visited[t] == 0 && (v == -1 || res[v] > res[t]))
			{
				v = t;
			}
		}
		if (v == -1 || res[v] >= 10000000)
		{
			break;
		}
		visited[v] = 1;
		for (EDGE* p = head[v]; p; p = p->next)
		{
			if (visited[p->to] == 0)
			{
				res[p->to] = min(res[p->to], res[v] + p->cost);
			}
		}
	}
	return res[to];
}
EDGE edges[20000];
int main()
{
	int is_prime[101];
	int ab_isprime[10000];
	memset(is_prime, 1, sizeof(is_prime));
	memset(ab_isprime, 1, sizeof(ab_isprime));
	is_prime[0] = is_prime[1] = 0;
	for (int i = 2; i * i < 10001;i++)
	{
		if (is_prime[i])
		{
			for (int j = 2 * i; j < 101;j += i)
			{
				is_prime[j] = 0;
			}
			for (int j = max(2, (1000 + i - 1) / i) * i; j < 10000; j += i)
			{
				ab_isprime[j] = 0;
			}
		}
	}
	vector<int> abPrimes;
	map<int, int> mapIndex;
	for (int i = 1000; i < 10000;i++)
	{
		if (ab_isprime[i])
		{
			abPrimes.push_back(i);
			mapIndex[i] = abPrimes.size() - 1;
		}
	}

	vector<EDGE*> head;
	head.resize(abPrimes.size(), NULL);
	int count = 0;
	for (int i = 0; i < abPrimes.size();i++)
	{
		for (int j = 0; j < abPrimes.size();j++)
		{
			int countofzero = 0;
			int div = 1;
			while (div <= 1000)
			{
				if ((abPrimes[i]/div) % 10 - abPrimes[j] / div % 10 == 0)
				{
					countofzero++;
				}
				div *= 10;
			}
			if (i == j)
			{
				continue;
			}
			if (countofzero == 3)
			{
				EDGE edge;
				edge.from = i;
				edge.to = j;
				edge.cost = 1;
				edge.next = head[i];
				EDGE invedge = edge;
				invedge.from = j;
				invedge.to = i;
				edges[count] = edge;;
				head[i] = &edges[count++];
				invedge.next = head[j];
				edges[count] = invedge;
				head[j] = &edges[count++];
			}
		}
	}
#ifdef _DEBUG
	freopen("d:\\in.txt", "r", stdin);
#endif
	int N;
	scanf("%d\n", &N);
	for (int i = 0; i < N;i++)
	{
		int a, b;
		scanf("%d %d\n", &a, &b);
		if (a == b)
		{
			printf("0\n");
		}
		else
		{
			printf("%d\n", Dij(mapIndex[a], mapIndex[b], head, abPrimes.size()));
		}
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章