POJ 1178 Floyd
来源:互联网 发布:北京六道口 知乎 编辑:程序博客网 时间:2024/04/28 21:50
先给一个我最先写的一个代码吧。总体思路是这样的,对于每个输入的点,都进行一次广搜,打出到达其他点的最短路径(这个效率相比于floyd太低了)再加在ans数组当中,最后搜索出最小值,并输出。虽然这个代码能过很多数据,但是 Discuss 里A1A2A3H2H5H6H7H8C1C2C5C6C7E2E3E4E5E6E7E8 就过不了。
至于原因还望大牛们给予指点。我预测可能是广搜有问题,我原以为,用广搜打出的路径表一定就严格递增的,所以我就这么写了,不过后来还是有问题,望各位指点啊。
我的错误代码如下:
#include <stdio.h>#include <iostream>#include <string.h>#include <queue>using namespace std;#define LEN 8#define MIN(a,b) (a<b?a:b)int ans[LEN][LEN];int king[LEN][LEN];int knight[LEN][LEN];int flag[LEN][LEN];int count = 0;int point[8][2] = {{-1, -2},{-1, 2},{1, -2},{1, 2},{-2, -1},{-2, 1},{2, -1},{2, 1}};/*void find(int x, int y, int n) {if(x < 0 || x >= LEN || y < 0 || y >= LEN) {return;}if(count > 128) return;count++;knight[x][y] = MIN(knight[x][y], n+1);find(x-1, y-2, knight[x][y]);find(x-1, y+2, knight[x][y]);find(x+1, y-2, knight[x][y]);find(x+1, y+2, knight[x][y]);find(x-2, y-1, knight[x][y]);find(x-2, y+1, knight[x][y]);find(x+2, y-1, knight[x][y]);find(x+2, y+1, knight[x][y]);}*/int _abs(int a) {return a < 0 ? (-a) : (a);}void find(int sx, int sy) {queue<int> queue;while(!queue.empty()) {queue.pop();}queue.push(sx);queue.push(sy);queue.push(0);flag[sx][sy] = 1;while(!queue.empty()) {int x = queue.front();queue.pop();int y = queue.front();queue.pop();int n = queue.front();queue.pop();for(int i = 0; i < 8; i++) {int xx = x+point[i][0];int yy = y+point[i][1];if(xx < 0 || xx >= LEN || yy < 0 || yy >= LEN) {continue;}if(flag[xx][yy]) {continue;}flag[xx][yy] = 1;knight[xx][yy] = n+1;queue.push(xx);queue.push(yy);queue.push(n+1);}}}void init() {for(int i = 0; i < LEN; i++) {for(int j = 0; j < LEN; j++) {knight[i][j] = 99999;}}knight[0][0] = 0;}void pr() {for(int i = 0; i < LEN; i++) {for(int j = 0; j < LEN; j++) {cout<< ans[i][j]<< " ";}cout<< endl;}cout<< endl;}void pri() {for(int i = 0; i < LEN; i++) {for(int j = 0; j < LEN; j++) {cout<< knight[i][j]<< " ";}cout<< endl;}cout<< endl;}int main() {char str[10000];int index, i, j, k;memset(king, 0, sizeof(king));memset(flag, 0, sizeof(flag));init();king[0][0] = 0;for(i = 1; i < LEN; i++) {king[0][i] = king[0][i-1] + 1;king[i][0] = king[i-1][0] + 1;}for(i = 1; i < LEN; i++) {for(j = 1; j < LEN; j++) {king[i][j] = MIN(king[i][j-1], MIN(king[i-1][j], king[i-1][j-1])) + 1;}}while(gets(str)) {memset(ans, 0, sizeof(ans));int k1 = str[0]-'A';int k2 = str[1]-'0'-1;for(i = 0; i < LEN; i++) {for(j = 0; j < LEN; j++) {ans[i][j] += _abs(king[i][j]-king[k1][k2]);}}//pr();for(index = 2; str[index] != '\0'; index += 2) {int t1 = str[index]-'A';int t2 = str[index+1] - '0' - 1;memset(knight, 0, sizeof(knight));memset(flag, 0, sizeof(flag));find(t1, t2);//pri();for(i = 0; i < LEN; i++) {for(j = 0; j < LEN; j++) {ans[i][j] += _abs(knight[i][j]-knight[t1][t2]);}}//pr();}int min = 99999;for(i = 0; i < LEN; i++) {for(j = 0; j < LEN; j++) {min = MIN(min, ans[i][j]);}}printf("%d\n", min);memset(str, 0, sizeof(str));}return 0;}
正确的 DP + floyd 解法, 其实最主要的就是把原来的那个 map 转换成为一个新的二维数组。
A1A2A3H2H5H6H7H8C1C2C5C6C7E2E3E4E5E6E7E8#include <cstdio>#include <iostream>#include <cstring>#include <string>using namespace std;#define MAX 8const int INF = (1<<20);int dirKing[8][2] = {{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,-1},{1,-1},{-1,1}};int dirKnight[8][2] = {{-2,-1},{-2,1},{2,-1},{2,1},{-1,-2},{1,-2},{-1,2},{1,2}};char str[MAX*MAX*2+5];int king[MAX*MAX][MAX*MAX], knight[MAX*MAX][MAX*MAX];int step[MAX*MAX], num;inline int min(int a,int b){ return a < b ? a : b;}void init(){ for(int i = 0; i < MAX*MAX; ++i) for(int j = 0; j < MAX*MAX; ++j) king[i][j] = knight[i][j] = (i == j ? 0 : INF); for(int i = 0; i < MAX*MAX; ++i) { int x = i/8; int y = i%8; for(int j = 0; j < 8; ++j) { int xx = x+dirKing[j][0]; int yy = y+dirKing[j][1]; if(xx >= 0 && xx < MAX && yy >= 0 && yy < MAX) king[i][8*xx+yy] = 1; } for(int j = 0; j < 8; ++j) { int xx = x+dirKnight[j][0]; int yy = y+dirKnight[j][1]; if(xx >= 0 && xx < MAX && yy >= 0 && yy < MAX) knight[i][8*xx+yy] = 1; } }}void floyd(int a[][MAX*MAX]){ for(int k = 0; k < MAX*MAX; ++k) { for(int i = 0; i < MAX*MAX; ++i) { for(int j = 0; j < MAX*MAX; ++j) { if(a[i][j] > a[i][k]+a[k][j]) a[i][j] = a[i][k]+a[k][j]; } } }}int main(){// freopen("input.txt","r",stdin); init(); floyd(king); floyd(knight); while(scanf("%s",str) != EOF) { int start = (str[0]-'A') + (str[1]-'1')*8; int num = (strlen(str)-2)/2; if(num == 0) { printf("0\n"); continue; } for(int i = 0, j = 2; i < num; ++i, j+=2) step[i] = (str[j]-'A') + (str[j+1]-'1')*8; int result = INF; int t1, t2; int sum; for(int i = 0; i < MAX*MAX; ++i) { sum = 0; for(int k = 0; k < num; ++k) sum += knight[ step[k] ][i]; for(int j = 0; j < MAX*MAX; ++j) { t1 = king[start][j]; t2 = INF; for(int kk = 0; kk < num; ++kk) { t2 = min(t2,knight[ step[kk] ][j] + knight[j][i] - knight[ step[kk] ][i]); } result = min(result,sum+t1+t2); } } printf("%d\n",result); } return 0;}
- POJ 1178 Floyd
- POJ 1178 Camelot (floyd+枚举)
- poj 1178 Camelot floyd + 枚举
- poj 1178 Camelot floyd+枚举
- POJ 1178 - Camelot (枚举+dp : floyd)
- POJ 1178 Camelot 最短路 Floyd +枚举
- POJ 1847 Floyd应用
- poj 1125 floyd算法
- POJ 2240 Arbitrage (Floyd)
- POJ 1125 Frogger (Floyd)
- poj 2240Arbitrage(Floyd)
- 【floyd】poj 3615
- POJ 2240 Arbitrage Floyd
- POJ 2253 Frogger Floyd
- POJ 1125 floyd水题
- POJ 1161 Floyd 构图
- POJ 2240 Floyd
- POJ-1125 FLOYD
- poj 3565 Ants(几何调整思想)
- 七夕,染红了我的相思
- android 多媒体文件之mp4分析(续)---base on jellybean(七)
- 设置Qt ui文件编译路径
- 浅析软件测试用例管理
- POJ 1178 Floyd
- jquery easy UI datagrid新增一行,columns中editor下拉框之间的联动。
- Python 代码性能优化技巧
- 给盒子的贺文
- 关于学习java的几点建议
- 学习C++标准库里面的string类(1)
- Java ArrayList排序
- 关于Socket网络编程
- 每个程序员都应该知道的8个Linux命令