A Famous Grid
Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1152 Accepted Submission(s): 451
Problem Description
Mr. B has recently discovered the grid named "spiral grid".
Construct the grid like the following figure. (The grid is actually infinite. The figure is only a small part of it.)
Considering traveling in it, you are free to any cell containing a composite number or 1, 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 of nonprime numbers, or report it's impossible.
Construct the grid like the following figure. (The grid is actually infinite. The figure is only a small part of it.)
Considering traveling in it, you are free to any cell containing a composite number or 1, 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 of nonprime numbers, or report it's impossible.
Input
Each test case is described by a line of input containing two nonprime integer 1 <=x, y<=10,000.
Output
For each test case, display its case number followed by the length of the shortest path or "impossible" (without quotes) in one line.
Sample Input
1 4 9 32 10 12
Sample Output
Case 1: 1 Case 2: 7 Case 3: impossible
Source
题目大意:上面介绍地很清楚了,按照上面的表,然后从一个合数到达另一个合数需要最小的步数。
解题思路:估计WZY当时敲题目也敲多了,当时也没搭配好,他写了有一段时间,然后又debug,貌似哪里出现了问题,看他写结构体都写了好几个。后来WA了一发,我仔细看了下题目,发现有bug,题目虽然说最大是10000,但是有的情况可以从外面绕,于是改成100w,爆内存,改成80w,又爆内存,50w,时间在1s+的时候WA了。于是又开大点。。当时因为这个贡献了八次的罚时,我想了下思路,按照这样肯定没问题,但是还是WA,最后还有十几分钟时峰峰说他们只开了1.2w,WZY的程序也不知道哪里出了点bug,打素数表没打到位?还是建立矩形表没建好。没找出来。。。今天自己写了一下,直接1A了。。我估计是他建表的时候哪里应该出了点问题。
题目地址:A Famous Grid
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#define maxn 20000
using namespace std;
int a,b;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int pa[1005][1005]; //存放放的数字t
int res[1005][1005];
int p[maxn][2]; //存储大小为t的横纵坐标
bool prim[maxn];
bool visi[maxn];
queue<int> mq;
void built() //建立矩形表
{
int ci,cj,i,tmp;
ci=500,cj=500;
p[1][0]=ci,p[1][1]=cj;
pa[ci][cj]=1;
int s=1;
while(1)
{
for(i=1;i<=s;i++) //向右
{
pa[ci][cj+i]=pa[ci][cj+i-1]+1;
tmp=pa[ci][cj+i];
p[tmp][0]=ci,p[tmp][1]=cj+i;
}
cj+=s;
for(i=1;i<=s;i++) //向上
{
pa[ci-i][cj]=pa[ci-i+1][cj]+1;
tmp=pa[ci-i][cj];
p[tmp][0]=ci-i,p[tmp][1]=cj;
}
ci-=s;
s++;
for(i=1;i<=s;i++)
{
pa[ci][cj-i]=pa[ci][cj-i+1]+1;
tmp=pa[ci][cj-i];
p[tmp][0]=ci,p[tmp][1]=cj-i;
}
cj-=s;
for(i=1;i<=s;i++)
{
pa[ci+i][cj]=pa[ci+i-1][cj]+1;
tmp=pa[ci+i][cj];
p[tmp][0]=ci+i,p[tmp][1]=cj;
}
ci+=s;
s++;
if(tmp>=15000) break;
}
}
void sxprim() //筛选素数
{
int i,j;
memset(prim,true,sizeof(prim));
prim[1]=false;
for(i=2;i<=sqrt(maxn+0.5);i++)
{
if(prim[i])
{
for(j=i*i;j<maxn;j+=i)
prim[j]=false;
}
}
}
void bfs()
{
while(!mq.empty())
mq.pop();
int i;
mq.push(a);
while(!mq.empty())
{
int tt=mq.front();
mq.pop();
if(tt==b)
{
break;
}
int tx=p[tt][0],ty=p[tt][1];
int mx,my,cur;
for(i=0;i<4;i++)
{
mx=tx+dir[i][0];
my=ty+dir[i][1];
cur=pa[mx][my];
if(!prim[cur]&&!visi[cur]&&cur<=14000)
{
mq.push(cur);
visi[cur]=true;
res[mx][my]=res[tx][ty]+1;
}
}
}
}
void output()
{
int i,j;
for(i=495;i<=505;i++)
{
for(j=495;j<=505;j++)
{
printf("%4d ",pa[i][j]);
}
cout<<endl;
}
cout<<p[3][0]<<" "<<p[3][1]<<endl;
for(i=1;i<=100;i++)
if(prim[i])
cout<<i<<" ";
cout<<endl;
}
int main()
{
built();
sxprim();
//output();
int cas=0;
while(cin>>a>>b)
{
if(a==b)
{
printf("Case %d: 0\n",++cas);
continue;
}
memset(visi,false,sizeof(visi));
memset(res,0,sizeof(res));
bfs();
int tx=p[b][0],ty=p[b][1];
if(res[tx][ty]==0)
printf("Case %d: impossible\n",++cas);
else
printf("Case %d: %d\n",++cas,res[tx][ty]);
}
return 0;
}
//953MS