• POJ 3009 Curling 2.0 题解 《挑战程序设计竞赛》


    题目:POJ3009 Curling 2.0

    思路:DFS + 回溯

    //照着别人的代码写的,测试数据输出正确,但没有AC,没有找到原因

    //经@Lorazepam 提示,下面这行代码的h和w写反了...

    66     while(scanf("%d %d", &h, &w) != EOF)

    //每个地图有n种路线,每条路线都会改变地图,因此每次搜索完毕得到结果(goal)后,要复原地图

    //每次递归DFS,就代表碰到了墙,需改变路线,因此要 step + 1

    //每条路线所用步数不同,题目求最小步数,因此要 goal = min(goal, step)

     1 #include <iostream>
     2 #include <stdio.h>
     3 
     4 using namespace std;
     5 
     6 int w;
     7 int h;
     8 const int INF = 0x3f3f3f3f; //常用的无穷大常量
     9 int goal;
    10 int res[100];
    11 int sx;
    12 int sy;
    13 int dx[4] = {-1, 0, 1, 0};
    14 int dy[4] = {0, 1, 0, -1};
    15 
    16 int board[25][25];
    17 
    18 bool isNotOut(int x, int y) {
    19     if(x < 0 || y < 0 || x >= h || y >= w) {
    20         return false;
    21     }
    22     return true;
    23 }
    24 
    25 
    26 void dfs(int step, int x, int y) {
    27     int nx;
    28     int ny;
    29     
    30     if(step > 10) {
    31         return ;
    32     }
    33     
    34     for(int i = 0; i < 4; i++) {
    35         nx = x + dx[i];
    36         ny = y + dy[i];
    37         
    38         if(!isNotOut(nx, ny)) {
    39             continue;  
    40         }
    41         if(board[nx][ny] == 1) {
    42             continue;
    43         }
    44         while(!board[nx][ny]) {
    45             nx += dx[i];
    46             ny += dy[i];
    47             if(!isNotOut(nx, ny)) {
    48                 break;
    49             }
    50         } 
    51         if(isNotOut(nx, ny)) {
    52             if(board[nx][ny] == 3) {
    53                 goal = min(goal, step);
    54             }
    55             if(board[nx][ny] == 1) {
    56                 board[nx][ny] = 0;
    57                 dfs(step + 1, nx - dx[i], ny - dy[i]);
    58                 board[nx][ny] = 1;
    59             }
    60         }
    61     }
    62 }
    63 
    64 int main() {
    65     int n = 0;
    66     while(scanf("%d %d", &h, &w) != EOF) {
    67         if(w == 0 && h == 0) {
    68             break;
    69         }
    70         for(int i = 0; i < h; i++) {
    71             for(int j = 0; j < w; j++) {
    72                 scanf("%d", &board[i][j]);
    73                 if(board[i][j] == 2) {
    74                     sx = i;
    75                     sy = j;
    76                     board[i][j] = 0;
    77                 }
    78             }
    79         }
    80         goal = INF;
    81         dfs(1, sx, sy);   
    82         res[n] = goal;
    83         n++;    
    84     }
    85     for (int i = 0; i < n; i++) {
    86         if(res[i] != INF) {
    87             printf("%d\n", res[i]);
    88         } else {
    89             printf("-1\n");
    90         }
    91     }
    92     return 0;
    93 } 

    额外收获:

    • while (scanf() != EOF) 或者 while (~scanf()),结合 if(w == 0 && h == 0) break; 用来判断测试数据输入完毕
  • 相关阅读:
    实现点击预览图片更改页面背景图片的效果
    JavaScript中赋值运算符的使用
    Visual Studio常用快捷键
    循 环 嵌 套
    控制摄像头拍照
    运用<body>属性,渲染页面效果
    子查询的易错点
    随机数
    PDO获取数据乱码的解决方法
    JavaScript中比较运算符的使用
  • 原文地址:https://www.cnblogs.com/carolunar/p/6351626.html
Copyright © 2020-2023  润新知