kattis - Prime Spiral
Boredom can be good for creativity. Polish mathematician Stanislaw Ulam (1909-1984) discovered the eponymous Ulam spiral while listening to a “long and very boring paper”. He started by writing down the positive integers in a spiral on a grid, one number per grid cell. Then he eliminated the composite numbers (i.e. non-primes). An interesting property he discovered was that the remaining prime numbers seem to form along many diagonals of the grid:
All positive integers
Only primes
Note that both of these are infinitely large grids, but due to physical constraints only a finite subset of the grid will fit in this space.
Let’s consider traveling around the second grid above (the Ulam spiral), where you are free to travel to any cell containing a composite number, but traveling to any cell containing a prime number is disallowed. You can travel up, down, left, or right, but not diagonally. Write a program to find the length of the shortest path between pairs composite numbers, if it is possible. Note, for example, that it is impossible to travel from the cells numbered 12 and 72 to any other composite cell. The length of a path is the number of steps on the path.
Input
Each test case is described by a line of input containing two integers 1≤x,y≤<?XML:NAMESPACE PREFIX = "[default] http://www.w3.org/1998/Math/MathML" NS = "http://www.w3.org/1998/Math/MathML" />1≤x,y≤10,000 which indicate two cells in the grid. Note that while there are limits on the input values, the intervening path between xx and yy is not limited in any way.
Output
For each case, display the case number followed by the length of the shortest path between the cells xx and yy, or “impossible” if no such path is possible.
Sample Input 1
Sample Output 1
1 4 9 32 10 12
Case 1: 1 Case 2: 7 Case 3: impossible
————————————————————————吐槽——————————————————————————————
这道题的大意是将1-10000的数字在一个100*100的方格里以一个环绕的形式摆好,如何环绕可以看图,然后将其中为素数的数字设为block,求任意两个不为素数之间的方块的最近距离,如果被阻隔导致无法到达,则输出impossible.
几个坑点:
一、最开始的最大值摆放可以在左上角的位置,这样才能达到和图一致的效果,如果从其他地方开始摆放应该是图形的旋转效果,对图本身的联通不造成任何影响,但是并没有经过试验
二、 最近距离由于该图是个四联通图,所以使用bfs,但是很久没做bfs竟然忘了bfs对于边界值要特殊处理这回事情了……嗯悲伤。bfs用队列来达成顺序处理的效果。
————————————————————————code——————————————————————————————
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<climits>
#include<map>
#include<stack>
#define file_in freopen("input.txt","r",stdin)
#define MAX 10005
#define maxn 5005
using namespace std;
#define LL long long
#define FF(x,y) for(int i=x;i<y;i++)
int mapp[102][102] = { 0 };
int vst[102][102] = { 0 };
int isp[MAX];
int minlen = INT_MAX;
struct node
{
int num;
int len;
};
queue<node>Q;
map<int, pair<int, int>>M;
int di[4] = { 0,0,1,-1 };
int dj[4] = { 1,-1,0,0 };node cnode(int x, int y)
{
node temp;
temp.num = x;
temp.len = y;
return temp;
}
int judge(int a, int b)
{
if (a > 0 && a < 101 && b>0 && b < 101)return 1;
else return 0;
}
void findp()
{
for (int i = 0; i<MAX; i++)
{
isp[i] = 1;
}
for (int i = 2; i<MAX; i++)
{
int it = 2;
if (!isp[i])continue;
while (i*it<MAX)
{
isp[i*it] = 0;
it++;
}
}
isp[1] = isp[0] = 0;
}void bfs(int sta, int tar)
{
Q.push(cnode(sta, 0));
while (!Q.empty())
{
node cur = Q.front();
Q.pop();
if (cur.num == tar)
{
minlen = cur.len;
return;
}
int i = M[cur.num].first, j = M[cur.num].second;
for (int k = 0; k < 4; k++)
{
if (!vst[i + di[k]][j + dj[k]]&&judge(i + di[k],j + dj[k]))
{
Q.push(cnode(mapp[i + di[k]][j + dj[k]], cur.len + 1));
vst[i + di[k]][j + dj[k]] = 1;
}
}
}
}
void intial()
{
findp();
int fi = 1, fj = 1;
int num = 10000;
for (int i = 0; i < 102; i++)
{
mapp[0][i] = 1;
mapp[101][i] = 1;
}
for (int i = 0; i < 102; i++)
{
mapp[i][0] = 1;
mapp[i][101] = 1;
}
while (num)
{
while (!mapp[fi][fj])
{
mapp[fi][fj++] = num--;
M[num + 1] = make_pair(fi, fj - 1);
}
fj--;
fi++;
while (!mapp[fi][fj])
{
mapp[fi++][fj] = num--;
M[num + 1] = make_pair(fi - 1, fj);
}
fi--;
fj--;
while (!mapp[fi][fj])
{
mapp[fi][fj--] = num--;
M[num + 1] = make_pair(fi, fj + 1);
}
fj++;
fi--;
while (!mapp[fi][fj])
{
mapp[fi--][fj] = num--;
M[num + 1] = make_pair(fi + 1, fj);
}
fi++;
fj++;}
for (int i = 1; i <= 100; i++)
for (int j = 1; j <= 100; j++)
if (isp[mapp[i][j]])vst[i][j] = 2;
}
int main()
{
intial();
int cnt = 0;
int a, b;
while (scanf("%d %d", &a, &b) != EOF)
{
printf("Case %d: ", cnt++ + 1);
minlen = INT_MAX;
bfs(a, b);
for (int i = 1; i <= 100; i++)
for (int j = 1; j <= 100; j++)
if (vst[i][j] == 1)
vst[i][j] = 0;
if (minlen != INT_MAX)
printf("%d\n", minlen);
else
printf("impossible\n");
}
}
/*
3
5
3 2
2 1
0 2
2 4
9
3 1
6 5
3 4
0 3
8 1
1 7
1 6
2 3
*/