首页 新闻 搜索 专区 学院

求教牛人帮忙看一下,poj2488我的程序的字典序为什么和答案不一样

0
悬赏园豆:10 [已关闭问题] 关闭于 2012-03-12 17:13

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

int n, p, q;

int used[26][26];
int pathX[26];
int pathY[26];
int dir[8][2] = { { -2, -1 }, { -2, 1 }, { -1, -2 }, { -1, 2 }, { 1, -2 }, { 1,
  2 }, { 2, -1 }, { 2, 1 } };
int ok;

void dfs(int x, int y, int step) {
 pathX[step - 1] = x;
 pathY[step - 1] = y;
 used[x][y] = 1;

 if (step == p * q) {
  ok = 1;
  return;
 }
 int i;
 for (i = 0; i < 8; i++) {
  int _x = x + dir[i][0];
  int _y = y + dir[i][1];

  if (_x >= 0 && _y >= 0 && _x < q && _y < p && !used[_x][_y]) {
   used[_x][_y] = 1;
   dfs(_x, _y, step + 1);
   used[_x][_y] = 0;
  }
 }

}

int main() {

 int sum = 0;
 cin >> n;

 while (n--) {
  cin >> p >> q;

  ok = 0;
  memset(used, 0, sizeof(used));
  memset(pathX, 0, sizeof(pathX));
  memset(pathY, 0, sizeof(pathY));

  printf("Scenario #%d:\n", ++sum);
  dfs(0, 0, 1);

  if (ok != 1) {
   printf("impossible\n");
  } else {
   for (int i = 0; i < p * q; i++) {
    printf("%c%d", pathX[i] + 'A', pathY[i] + 1);
   }
   printf("\n");
  }

  printf("\n");

 }
 return 0;
}

warm3snow的主页 warm3snow | 初学一级 | 园豆:191
提问于:2012-03-12 17:03
< >
分享
所有回答(1)
1

你的算法理解没有什么问题,可能是有点粗心了。

1:dfs中if (_x >= 0 && _y >= 0 && _x < q && _y < p && !used[_x][_y]) 写错了应该是:

if (_x >= 0 && _y >= 0 && _x < p && _y < q && !used[_x][_y])

2:输出的时候 printf("%c%d", pathX[i] + 'A', pathY[i] + 1);写错了,Y轴是字母,X轴是数字,应该是:

 printf("%c%d", pathY[i] + 'A', pathX[i] + 1);

 

zsounder | 园豆:2819 (老鸟四级) | 2012-03-12 18:04

修改之后还是WA,下面的结果显然和所给的不一样

5
4 3
Scenario #1:
A1B3C1A2B4C2A3C4B2A4C3B1

5 5
Scenario #2:
A1B3C5E4C3D5B4D3E5C4A5C2D4B5A3B1D2A2B2A4C1A2E1A4A5

支持(0) 反对(0) warm3snow | 园豆:191 (初学一级) | 2012-03-13 21:07

@informatics: 

嗯,还有一个问题:

if (_x >= 0 && _y >= 0 && _x < q && _y < p && !used[_x][_y]) {
used[_x][_y] = 1;
dfs(_x, _y, step + 1);
used[_x][_y] = 0;
}

上面设置used[_x][_y] = 1;是多余的,因为所有的访问在外层访问的时候都已经标记了。

如果从dfs退出,说明这一步走的不对,退回上一步,同时在最后设置used[x][y] = 0;

 

整理后的代码:

#include "stdafx.h"
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int n, p, q;
int used[26][26];
int pathX[26];
int pathY[26];
int dir[8][2] = { { -2, -1 }, { -2, 1 }, { -1, -2 }, { -1, 2 }, { 1, -2 }, { 1,
2 }, { 2, -1 }, { 2, 1 } };
int ok;
void dfs(int x, int y, int step) {
pathX[step - 1] = x;
pathY[step - 1] = y;
used[x][y] = 1;
if (step == p * q) {
ok = 1;
return;
}
int i;
for (i = 0; i < 8; i++) {
int _x = x + dir[i][0];
int _y = y + dir[i][1];
if (_x >= 0 && _y >= 0 && _x < p && _y < q && !used[_x][_y]) {
dfs(_x, _y, step + 1);
}
}
used[x][y] = 0;
}
int main() {
int sum = 0;
cin >> n;
while (n--) {
cin >> p >> q;
ok = 0;
memset(used, 0, sizeof(used));
memset(pathX, 0, sizeof(pathX));
memset(pathY, 0, sizeof(pathY));
printf("Scenario #%d:\n", ++sum);
dfs(0, 0, 1);
if (ok != 1) {
printf("impossible\n");
} else {
for (int i = 0; i < p * q; i++) {
printf("%c%d", pathY[i] + 'A', pathX[i] + 1);
}
printf("\n");
}
printf("\n");
}
return 0;
}






支持(0) 反对(0) zsounder | 园豆:2819 (老鸟四级) | 2012-03-13 23:00

@informatics: 

if (_x >= 0 && _y >= 0 && _x < q && _y < p && !used[_x][_y]) {
used[_x][_y] = 1;
dfs(_x, _y, step + 1);
used[_x][_y] = 0;
}
对于当前位置x,y,首先设置访问标记为1,然后以当前位置为起点,8个方向搜索,如果在搜索过程中发现当前的step和格子数目相等说明成功;如果从当前位置搜索8个方向后发现step和格子数目不相等,说明当前这个搜索方向不对,则这只当前的访问标记为0,退回去,进行下一个方向的搜索。
你的for里面没有必要对下一个访问方向设置访问标记位,因为下面进行dfx的时候会进行标记位的设置。所以应该在最后设置
used[x][y] = 0;。
    
支持(0) 反对(0) zsounder | 园豆:2819 (老鸟四级) | 2012-03-13 23:19
支持(0) 反对(0) zsounder | 园豆:2819 (老鸟四级) | 2012-03-13 23:31

@informatics:  你的代码修改之后执行:点这里

支持(0) 反对(0) zsounder | 园豆:2819 (老鸟四级) | 2012-03-15 18:20

@Wang Hui: 谢谢。。。。。

支持(0) 反对(0) warm3snow | 园豆:191 (初学一级) | 2012-03-21 23:24
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册