• POJ 3009 Curling 2.0


    题目链接:https://vjudge.net/problem/POJ-3009

    题目大意:

      冰壶比赛。

    给定一个 n * m 的矩阵A,其中:

    1. A[i][j] == 0,代表通路。
    2. A[i][j] == 1,代表冰块。
    3. A[i][j] == 2,代表冰壶起点。
    4. A[i][j] == 3,代表冰壶所要到达的点。

    冰壶只能往上下左右四个方向移动,且碰到冰块才会停下来,同时冰块也会碎掉,冰壶也随之停在原地,冰壶一旦打出界,比赛就结束了,冰壶只要在10步以内经过终点,就算成功。

    求每场冰壶比赛的最小移动步数。

    分析:

      dfs基础题,读懂题目最重要。

    代码如下:

      1 //#include <bits/stdc++.h>
      2 
      3 // POJ 用 start 
      4 #include<cstdio>  
      5 #include<cstring>  
      6 #include<algorithm>  
      7 #include<iostream>  
      8 #include<string>  
      9 #include<vector>  
     10 #include<stack>  
     11 #include<bitset>  
     12 #include<cstdlib>  
     13 #include<cmath>  
     14 #include<set>  
     15 #include<list>  
     16 #include<deque>  
     17 #include<map>  
     18 #include<queue>  
     19 // POJ 用 end 
     20 
     21 using namespace std;
     22 
     23 /*-------------------Define Start-------------------*/
     24 typedef bool BL;                        // 布尔类型
     25 typedef char SB;                        // 有符号1字节,8位
     26 typedef unsigned char UB;                // 无符号1字节,8位
     27 typedef short SW;                        // 有符号短整型,16位
     28 typedef unsigned short UW;                // 无符号短整型,16位
     29 typedef long SDW;                        // 有符号整型,32位
     30 typedef unsigned long UDW;               // 无符号整型,32位
     31 typedef long long SLL;                    // 有符号长整型,64位
     32 typedef unsigned long long ULL;            // 无符号长整型,64位
     33 typedef char CH;                        // 单个字符
     34 typedef float R32;                        // 单精度浮点数
     35 typedef double R64;                        // 双精度浮点数
     36 
     37 #define Rep(i, n) for (register SDW i = 0; i < (n); ++i)
     38 #define For(i, s, t) for (register SDW i = (s); i <= (t); ++i)
     39 #define rFor(i, t, s) for (register SDW i = (t); i >= (s); --i)
     40 #define foreach(i, c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
     41 #define ms0(a) memset(a,0,sizeof(a))
     42 #define msI(a) memset(a,0x7f,sizeof(a))
     43 #define LOWBIT(x) ((x)&(-x))
     44 
     45 #define MP make_pair
     46 #define PB push_back
     47 #define ft first
     48 #define sd second
     49 
     50 #define pr(x) cout << #x << " = " << x << "  "
     51 #define prln(x) cout << #x << " = " << x << endl
     52 
     53 const ULL mod = 1e9 + 7;                //常用模数(可根据题目需要修改)
     54 const ULL inf = 0x7fffffff;                //用来表示无限大
     55 const ULL infLL = 0x7fffffffffffffffLL;    //用来表示无限大
     56 /*-------------------Define End-------------------*/
     57 
     58 struct Point{
     59     SDW X, Y;
     60     
     61     Point(SDW x = 0, SDW y = 0) : X(x), Y(y) {}
     62     
     63     void set(SDW x, SDW y) {
     64         X = x;
     65         Y = y;
     66     }
     67     
     68     Point operator+ (const Point& x) { return Point(X + x.X, Y + x.Y); }
     69     BL operator== (const Point& x) const { return X == x.X && Y == x.Y; }
     70     BL operator!= (const Point& x) const { return !(*this == x); }
     71 }; 
     72 
     73 const UDW maxN = 2e1 + 7;
     74 SDW N, M;
     75 SDW field[maxN][maxN];
     76 Point S, G;
     77 Point dir[] = {Point(0, -1), Point(-1, 0), Point(0, 1), Point(1, 0)};
     78 SDW ans;
     79 
     80 void input(){
     81     ans = inf;
     82     Rep(i, N) {
     83         Rep(j, M) {
     84             cin >> field[i][j];
     85             if(field[i][j] == 2) {
     86                 S.set(i, j);
     87             }
     88             if(field[i][j] == 3) {
     89                 G.set(i, j);
     90             }
     91         }
     92     }
     93 }
     94 
     95 BL isPass(Point x, Point y) {
     96     if(x.X == y.X) {
     97         return x.X == G.X && min(x.Y, y.Y) <= G.Y && G.Y <= max(x.Y, y.Y);
     98     }
     99     else {
    100         return x.Y == G.Y && min(x.X, y.X) <= G.X && G.X <= max(x.X, y.X);
    101     }
    102 } 
    103 
    104 // 查找冰壶所能移动到的最左位置 
    105 Point leftMost(Point x) {
    106     while(x.Y > 0 && field[x.X][x.Y - 1] != 1) {
    107         --x.Y;
    108     }
    109     return x;
    110 }
    111 
    112 // 查找冰壶所能移动到的最上位置 
    113 Point upMost(Point x) {
    114     while(x.X > 0 && field[x.X - 1][x.Y] != 1) {
    115         --x.X;
    116     }
    117     return x;
    118 }
    119 
    120 // 查找冰壶所能移动到的最右位置 
    121 Point rightMost(Point x) {
    122     while(x.Y < M - 1 && field[x.X][x.Y + 1] != 1) {
    123         ++x.Y;
    124     }
    125     return x;
    126 }
    127 
    128 // 查找冰壶所能移动到的最下位置 
    129 Point downMost(Point x) {
    130     while(x.X < N - 1 && field[x.X + 1][x.Y] != 1) {
    131         ++x.X;
    132     }
    133     return x;
    134 }
    135 
    136 Point (*func[4])(Point) = {leftMost, upMost, rightMost, downMost};
    137 
    138 void dfs(Point p, SDW cnt) {
    139     if(cnt > 10) {
    140         return;
    141     }
    142     
    143     Rep(i, 4) {
    144         Point nextP = func[i](p);        // 冰壶的下一个出发点 
    145         Point blockP = nextP + dir[i];    // 冰壶撞到的冰块的位置或者边界位置 
    146         
    147         if(isPass(p, nextP)) {             // 经过了目标点 
    148             ans = min(ans, cnt + 1);
    149             return;
    150         }
    151         if(p != nextP && blockP.X >= 0 && blockP.X < N && blockP.Y >= 0 && blockP.Y < M) {
    152             field[blockP.X][blockP.Y] = 0;
    153             dfs(nextP, cnt + 1);
    154             field[blockP.X][blockP.Y] = 1;
    155         }
    156     }
    157 }
    158 
    159 void solve(){
    160     dfs(S, 0);
    161     if(ans > 10) {
    162         ans = -1;
    163     }
    164 }
    165 
    166 void output(){
    167     cout << ans << endl;
    168 }
    169 
    170 int main() {
    171     while((cin >> M >> N) && M) {
    172         input();
    173         solve();
    174         output();
    175     }
    176     return 0;
    177 }
    View Code
  • 相关阅读:
    C#线程优先级浅析
    Android常用组件
    Android 内存监测工具 DDMS --> Heap
    Android 十个非常漂亮的常用组件
    RelativeLayout 相对布局 常用属性
    Android 关于横竖屏
    (转)Android 之 StrictMode 介绍
    Android如何获取SIM卡信息
    Android 读SIM卡信息
    Android Camera 使用小结
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/10803395.html
Copyright © 2020-2023  润新知