zoukankan      html  css  js  c++  java
  • 【上海交大oj】梅西的过人

    题目描述

    梅西来SJTU了!这让交大学子沸腾了,为了体现阿根廷和中国的国际友谊,校长决定让梅西与电院组织一场友谊赛。这场比赛在南体进行,把南体分成一个n乘m的矩阵,一开始梅西在(1,1)位置,球门在(n,m)位置,只要梅西能带球到球门处就算梅西胜利。电院几乎派出了所有学生来阻挡梅西,但是因为梅西的气场,他们站在场上都不敢动。 如下图,是一个3乘4的球场,每个位置上的数字表示这个位置有没有站电院的学生。m是梅西,d是球门。
    m 0 1 0
    0 0 1 0
    1 0 1 d
    同时,为了公平起见,限定梅西只能过一个人,就是说梅西能跨入“1”的格子,但只能进入一次。同时规定梅西只能四方向移动,就是说梅西不能从一个格子走到它右上角的格子。 在上面的这个例子中,梅西能通过过一个人来走到球门处。
    m 1 0 0
    1 1 1 1
    0 0 1 d
    但在这个例子中,梅西就到不了了,因为他必须过两个人。
    在球场上没有时间给你思考!只有一秒钟时间在决定能否到球门处。

    输入

    k组数据,给出n,m,分别是矩阵的行数和列数,之后给出n行,每行m个数,每个数是0或者1,在(1,1)和(n,m)必是0。表示在这个位置上是否有电院的学生。
    Sample input 1:
    1
    3 4
    0 0 1 0
    0 0 1 0
    1 0 1 0

    输出

    输出k行,给出梅西是否能到达球门,1表示能,0表示不能。
    Sample output 1:
    1

    数据范围:

    对50%的数据  3<=N,m<=100
    对100%的数据 3<=N,m<=1000,k<=4

    ====================================
    想法很简单,就是开头结尾bfs,看看能不能找到一条公共边界,但是由于开始对广度优先的理解不够到位,很愚蠢地开了一个二维数组作为open表,结果每次查找open表中的点都要扫描一遍,结果可想而知,O(n^4)的复杂度自然过不了。然后发现了c++标准库的queue,顺利解决。代码如下(有点啰嗦,可惜不会优化):
      1 //梅西的过人 
      2 #include <iostream>
      3 #include <queue> 
      4 using namespace std;
      5 
      6 struct point {
      7     int raw;
      8     int col;
      9 };
     10 int main(){
     11     int k,n,m,i,j,q,r,c;
     12     queue<point>open;
     13 
     14     cin>>k;
     15     bool flag[k];
     16     for (i=0;i<k;++i) {
     17         cin>>n>>m;
     18         flag[i] = 0;
     19         bool map[n][m];
     20         int state[n][m]; // 0表示能到达 2表示不能到达 1表示边界 
     21         //初始化 
     22         while (open.size()>0) open.pop();
     23         for (j=0;j<n;++j)
     24             for (q=0;q<m;++q) {
     25                 cin>>map[j][q];
     26                 state[j][q]=2;
     27             }
     28         //左上角开始扫描    
     29         point point_in = {0,0};
     30         open.push(point_in);
     31         while (1) {//cout<<1;
     32             if (open.size()==0) break;
     33             point point_out = open.front();
     34             open.pop();
     35             r =point_out.raw;
     36             c = point_out.col;
     37             if (r==n-1 && c==m-1) {
     38                 flag[i] = 1;
     39                 break;
     40             }            
     41             state[r][c] = 0;
     42             if (r>0) {
     43                 if (!map[r-1][c]) {
     44                     if (state[r-1][c]==2) {
     45                         point_in.raw = r-1;
     46                         point_in.col = c;
     47                         open.push(point_in);
     48                     }
     49                     state[r-1][c] = 0;
     50                 }else state[r-1][c] = 1;
     51             }
     52             if (r<n-1) {
     53                 if (!map[r+1][c]) {
     54                     if (state[r+1][c]==2) {
     55                         point_in.raw = r+1;
     56                         point_in.col = c;
     57                         open.push(point_in);
     58                     }
     59                     state[r+1][c] = 0;
     60                 }else state[r+1][c] = 1;
     61             }    
     62             if (c>0) {
     63                 if (!map[r][c-1]) {
     64                     if (state[r][c-1]==2) {
     65                         point_in.raw = r;
     66                         point_in.col = c-1;
     67                         open.push(point_in); 
     68                     }
     69                     state[r][c-1] = 0;
     70                 }
     71                 else state[r][c-1] = 1;
     72             }                
     73             if (c<m-1) {
     74                 if (!map[r][c+1]) {
     75                     if (state[r][c+1]==2) {
     76                         point_in.raw = r;
     77                         point_in.col = c+1;
     78                         open.push(point_in);
     79                     }
     80                     state[r][c+1] = 0;
     81                 }
     82                 else state[r][c+1] = 1;
     83             }                                        
     84         }
     85         if (flag[i]) continue; //判断直接左上角是否有通道
     86         //若无,从右下角开始bfs,判断是否能到达边界 
     87         point_in.raw = n-1;
     88         point_in.col = m-1;    
     89         open.push(point_in);
     90         while (1) {
     91             if (open.size()==0) break;
     92             point point_out = open.front();
     93             r = point_out.raw;
     94             c = point_out.col;
     95             open.pop();
     96             state[r][c] = 0;
     97             if (r>0) {
     98                 if (state[r-1][c]==1) {
     99                     flag[i] = 1;
    100                     break;
    101                 }else if (state[r-1][c]==2) {
    102                     if (!map[r-1][c]) {
    103                         point_in.raw = r-1;
    104                         point_in.col = c;
    105                         open.push(point_in);
    106                         state[r-1][c] = 0;
    107                     }else state[r-1][c] = -1;
    108                 }    
    109             }
    110             if (r<n-1) {
    111                 if (state[r+1][c]==1) {
    112                     flag[i] = 1;
    113                     break;
    114                 }else if (state[r+1][c]==2) {
    115                     if (!map[r+1][c]) {
    116                         point_in.raw = r+1;
    117                         point_in.col = c;
    118                         open.push(point_in);
    119                         state[r+1][c] = 0;
    120                     }else state[r+1][c] = -1;
    121                 }    
    122             }    
    123             if (c>0) {
    124                 if (state[r][c-1]==1) {
    125                     flag[i]=1;
    126                     break;
    127                 }else if (state[r][c-1]==2) {
    128                     if (!map[r][c-1]) {
    129                         point_in.raw = r;
    130                         point_in.col = c-1;
    131                         open.push(point_in);
    132                         state[r][c-1] = 0;
    133                     }else state[r][c-1] = -1;
    134                 }
    135             }                
    136             if (c<m-1) {
    137                 if (state[r][c+1]==1) {
    138                     flag[i]=1;
    139                     break;
    140                 }else if (state[r][c+1]==2) {
    141                     if (!map[r][c+1]) {
    142                         point_in.raw = r;
    143                         point_in.col = c+1;
    144                         state[r][c+1] = 0;
    145                     }    
    146                 }else state[r-1][c+1] = -1;
    147             }                                
    148         } 
    149     } 
    150     for (i=0;i<k;++i) {
    151         if (flag[i]) cout<<1<<endl; 
    152         else cout<<0<<endl;
    153     }
    154     return 0;
    155 }


  • 相关阅读:
    angularjs学习笔记一之显示数据,修改数据
    收藏/不再提醒
    CSS3动画
    Content-Type
    键盘快捷键
    url、href、src 详解
    关于docnment.write() 会清空原来的内容
    jq事件注意点
    echart的自适应
    键盘事件
  • 原文地址:https://www.cnblogs.com/wenma/p/4474722.html
Copyright © 2011-2022 走看看