[原]poj-2488-water-DFS

题目大意: 输入一个p*q的棋盘, 行用数字表示, 列用大写字母表示 , 1 <= p*q <= 26, 输出能够把棋盘全部空格走完且每个空格只走一次的字典序最小的路径。不存在则输出“impossible”

坑の所在: 行列的表示, 每组解后有一空行。

思路: 八方向dfs,方向数组要按字典序排列, 记录步数, 最先找到的一组解便是字典序最小解,便可停止搜索。


AC代码:

#include<iostream>
#include<cstdio>
using namespace std;
int p, q;
bool vis[30][30];
int d[8][2] = { -1,-2, 1,-2, -2,-1, 2,-1, -2,1, 2,1, -1,2, 1, 2 };
struct node{
   int x, y;
}next[30][30];
bool check(int a, int b)
{
   if(a >= 0 && a < p && b >= 0 && b < q) return true;
   return false;
}
bool stop;
void init()
{
   for(int i = 0; i < 30; i++)
      for(int k = 0; k < 30; k++){
         vis[i][k] = false;
         next[i][k].x = next[i][k].y = -1;
      }
   vis[0][0] = true;
   stop = 0;
}
void dfs(int a, int b, int step)
{
   if(step == p*q) {
      stop = true;
      return;
   }
   for(int i = 0; i < 8; i++){
      int dx = a + d[i][0];
      int dy = b + d[i][1];
      if(check(dx, dy) && !vis[dx][dy]){
         next[a][b].x = dx;
         next[a][b].y = dy;
         vis[dx][dy] = true;
         //cout<<a<<" "<<b<<" "<<next[a][b].x<<" "<<next[a][b].y<<endl;
         dfs(dx, dy, step+1);
         if(stop) return;
         vis[dx][dy] = false;
      }
   }
}
void output()
{
   int a = 0, b = 0, t, step = 1;
   printf("%c%d", a+'A', b+1);
   while(step < p*q){
      printf("%c%d", next[a][b].y+'A', next[a][b].x+1);
      t = a;
      a = next[a][b].x;
      b = next[t][b].y;
      step++;
   }
   printf("\n");
}

int main()
{
   int T;
   cin>>T;
   for(int k = 1; k <= T; k++){
      scanf("%d%d", &p, &q);
      init();
      dfs(0, 0, 1);
      printf("Scenario #%d:\n", k);
      if(stop) output();
      else printf("impossible\n");
      if(k != T)printf("\n");
   }
   return 0;
}



作者:u011652573 发表于2014-6-1 15:36:08 原文链接
阅读:33 评论:0 查看评论

 

转载于:https://www.cnblogs.com/ZiningTang/p/3834741.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值