http://acm.hdu.edu.cn/showproblem.php?pid=4255
这题还是很有意思的
打了两个表
一个是矩阵的
一个是素数表
然后直接BFS
不过好多天没写ACM题
今天手感实在是不行啊。。。弱爆了
这题唯一有问题的就是可能存在一条路,这条路经过大于1W数字的点了
标程提供的是200*200
DHT大神给我讲了之后,他说用400*400,然后一改就过了。。跪到惨了
今天还遇到个写文件 的问题,真心不解,下次再碰到就好好研究吧,还是赶紧去做信安大赛吧
#include<cstdio> #include<queue> #include<cstring> using namespace std; struct point{ int x, y; int step; }; struct MAP{ int x, y; }Map[160010]; int map[410][410]; void init(){ Map[160000].x = Map[160000].y = 1; map[1][1] = 160000; int n = 159999; //while() int row = 399; int m = 200; int x = 1, y = 1; while(m --){ for(int i = 0 ; i < row; i ++){ y ++; Map[n].x = x, Map[n].y = y; map[x][y] = n; n--; } for(int i = 0 ; i < row; i ++){ x ++; Map[n].x = x, Map[n].y = y; map[x][y] = n; n--; } for(int i = 0 ; i < row; i ++){ y --; Map[n].x = x, Map[n].y = y; map[x][y] = n; n--; } for(int i = 0 ; i < row-1; i ++){ x --; Map[n].x = x, Map[n].y = y; map[x][y] = n; n--; } row -= 2; y ++; Map[n].x = x, Map[n].y = y; map[x][y] = n; n --; } map[201][201] = 2; Map[2].x = 201, Map[2].y = 201; /* //printf("------%d %d\n", Map[1].x,Map[1].y); printf("++++ %d\n", map[94][94]); for(int i = 93; i <= 100; i ++) { for(int j = 1; j <= 100; j ++) { //if(map[i][j] == 0)puts("asf"); printf("%d ", map[i][j]); } puts(""); } */ } const int maxn = 160000 + 10; bool IsNotPrime[maxn]; // 判断是否为素数. int PrimeList[maxn]; // 素数列表. int PrimeNum; void Prime_Linear() { // 速度比朴素筛法快2倍以上,该筛法进行稍微修改即可用于求欧拉函数Phi[]. int i, j; memset(IsNotPrime, 0, sizeof(IsNotPrime)); // 初始赋值所有数都是素数. IsNotPrime[1] = 1; IsNotPrime[0] = 1; // 0和1不是素数. PrimeList[0]=2; for (i = 4; i < maxn; i += 2) IsNotPrime[i] = 1; // 除2以外的所有偶数都不是素数. PrimeNum = 1; for (i = 3; i < maxn; i += 2) { if (!IsNotPrime[i]) { // 如果是素数则加入素数列表. PrimeList[PrimeNum++] = i; } // 注意:这里与朴素筛法不同,即使合数也要进行筛. // 因为这里素数只筛它的素数倍,那么有些合数就可能没被筛掉. // 而这些合数就需要合数来晒,而且只要筛到它的最小质因子倍即可(想想为什么?). for (j = 0; j < PrimeNum && i * PrimeList[j] < maxn; j++) { IsNotPrime[i * PrimeList[j]] = 1; if (i % PrimeList[j] == 0) { // 说明PrimeList[j]是i的最小质因子,即i * PrimeList[j]的最小质因子,则跳出. break; } } } } int dir[4][2] = {-1,0,1,0,0,-1,0,1}; bool flag[410][410]; int bfs(point start, point end){ queue < point > q; q.push(start); while(!q.empty()){ point tmp = q.front(); q.pop(); for(int i = 0; i < 4; i ++){ int x = tmp.x + dir[i][0]; int y = tmp.y + dir[i][1]; if(x == end.x && y == end.y ){ return tmp.step+1; } if(x < 1 || y < 1 || x > 400 || y > 400)continue; if(flag[x][y] == 1) continue; //intf("--%d\n", map[x][y]); if(IsNotPrime[ map[x][y] ] == 0)continue; point now; now.x = x; now.y = y; now.step = tmp.step + 1; q.push(now); flag[now.x][now.y] = 1; } } return 0; } int main(){ // freopen("c:\\12.txt","w",stdout); init(); Prime_Linear(); int z = 1; int x, y; while(~scanf("%d%d", &x, &y)){ memset(flag, 0, sizeof(flag)); point start, end; start.x = Map[x].x; start.y = Map[x].y; start.step = 0; flag[start.x][start.y] = 1; end.x = Map[y].x; end.y = Map[y].y; int f = bfs(start, end); printf("Case %d: ", z ++); if(f != 0) printf("%d\n", f); else puts("impossible"); } return 0; }