zoukankan      html  css  js  c++  java
  • hdoj1175 连连看(dfs+剪枝)

    处理连连看问题。

    要求拐弯方向不多于两次。剪枝很重要!!!

    用dir记录当前方向。Orz,居然没想到。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<algorithm>
     4 #define maxn 1005
     5 using namespace std;
     6 const int dx[]={-1,1,0,0},dy[]={0,0,-1,1};
     7 int map[maxn][maxn],V[maxn][maxn];
     8 int n,m,flag,x1,x2,y1,y2;
     9 void dfs(int x,int y,int num,int dir){
    10     if (flag || x<0 || x>=n || y<0 || y>=m || V[x][y]) return ;
    11     if (num==2 && x!=x2 && y!=y2) return ;//当拐弯数为2,但与终点不在同一方向 
    12     if (num>2) return ;
    13     if (num<=2 && x==x2 && y==y2){
    14         flag=1;
    15         return ;
    16     } 
    17     if (map[x][y]!=0){
    18         if (x==x1 && y==y1) ;
    19         else return ;
    20     }//当前不为零且不为起点,即路径上有棋子 
    21     V[x][y]=1;
    22     for (int i=0;i<4;i++){
    23         int xx=x+dx[i],yy=y+dy[i];
    24         if (i==dir) dfs(xx,yy,num,i);
    25         else dfs(xx,yy,num+1,i);
    26     }
    27     V[x][y]=0;
    28     return ;
    29 }
    30 int main(){
    31     int t;
    32     while (cin >> n >> m && n+m){
    33         memset(map,0,sizeof(map));
    34         for (int i=0;i<n;i++){
    35             for (int j=0;j<m;j++){
    36                 cin >> map[i][j];
    37             }
    38         }
    39         cin >> t;
    40         while (t--){
    41             cin >> x1 >> y1 >> x2 >> y2;
    42             x1--,y1--,x2--,y2--;
    43             if (x1==x2 && y1==y2){
    44                 cout << "NO
    ";
    45                 continue;
    46             }//起点与终点相同不能消去
    47             if (map[x1][y1]!=map[x2][y2] || !map[x1][y1] || !map[x2][y2]){
    48                 cout << "NO
    ";
    49                 continue;
    50             }//起点与终点不同,或起点或终点位置没有棋子
    51             if (x1<0 || x1>=n || y1<0 || y1>=m || x2<0 || x2>=n || y2<0 || y2>=m){
    52                 cout << "NO
    ";
    53                 continue;
    54             }//所给坐标超出当前范围
    55             flag=0;
    56             memset(V,0,sizeof(V));
    57             for (int i=0;i<n;i++){
    58                 dfs(x1+dx[i],y1+dy[i],0,i); //从一个点的四个方向开始 ,拐弯数 ,当前方向 
    59             } 
    60             if (flag) cout << "YES
    ";
    61             else cout << "NO
    "; 
    62         }
    63     }
    64     return 0;
    65 }
  • 相关阅读:
    Oracle如何定义两个数组变量
    Oracle 数组定义
    Oracle的Number对应C#数据类型
    Oracle删除临时表
    我的第一个Flutter 项目(电商)
    Dart Mac 安装环境(无敌)
    React Native 问题(运行)
    TS的一些用法和普通的对比(Vue)
    vue2.0和vue3.0的响应式原理
    简易orm 主要是为了旧平台查询方便
  • 原文地址:https://www.cnblogs.com/changer-qyz/p/8486360.html
Copyright © 2011-2022 走看看