zoukankan      html  css  js  c++  java
  • CF 1912 A NEKO's Maze Game

    题目传送门

    题目描述

    输入

    输出

    样例

    样例输入

    5 5
    2 3
    1 4
    2 4
    2 3
    1 4
    View Code

    样例输出

    Yes
    No
    No
    No
    Yes
    View Code

    一句话题意:2*n的迷宫,从(1,1)出发到(2,n),初始时全部的都是地面,每次询问会把一个地面给变成熔浆,熔浆变成地面,熔浆不能通过,问是否可以走到。

    分析

    我们先开一个a数组存储每个方格当前的状态,0表示地面,1表示熔岩

    在一个长度为n,宽度为2的迷宫中,有三种情况不能从(1,1)走到(2,n)

    情况一
    0 1 0 0 0
    0 1 0 0 0
    情况二
     0 1 0 0 0
    0 0 1 0 0
    情况三
    0 0 1 0 0
    0 1 0 0 0

    情况一:a[1][n]和a[2][n]同时为1

    情况二:a[1][n]和a[2][n+1]同时为1 或 a[2][n]和a[1][n+1]同时为1

    情况三:a[1][n]和a[2][n-1]同时为1 a[2][n]和a[1][n-1]同时为1

    在其他情况下,总能通过别的点到达(2,n)

    如果我们一个一个去枚举的话,那么1e5的数据肯定会超时

    所以我们可以记录一下以上三种情况出现的次数,当次数不为0时,输出No,否则输出Yes

    写代码的时候再考虑一下边界问题就可以了

    代码

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<cstring>
     6 using namespace std;
     7 const int maxn=1e5+5;
     8 int ans=0;
     9 int a[3][maxn];
    10 int main(){
    11     int n,q;
    12     scanf("%d%d",&n,&q);
    13     for(int i=1;i<=q;i++){
    14         int aa,bb;
    15         scanf("%d%d",&aa,&bb);
    16         if(a[aa][bb]==1){
    17             a[aa][bb]=0;
    18             if(aa==1){
    19                 if(a[2][bb]==1) ans--;
    20                 if(a[2][bb+1]==1 && bb+1<=n) ans--;
    21                 if(a[2][bb-1]==1 && bb>1) ans--;
    22             } else {
    23                 if(a[1][bb]==1) ans--;
    24                 if(a[1][bb+1]==1 && bb+1<=n) ans--;
    25                 if(a[1][bb-1]==1 && bb>1) ans--;
    26             }//如果这个点是由岩浆变成地面的话,之前算出来的ans就要更新
    27             //因为之前形成断路的地方现在不一定还有断路
    28             if(ans==0) printf("Yes
    ");
    29             else printf("No
    ");
    30         } else {
    31             a[aa][bb]=1;
    32             if(aa==1){
    33                 if(a[2][bb]==1) ans++;
    34                 if(a[2][bb+1]==1 && bb+1<=n) ans++;//bb+1<=n防止超出边界
    35                 if(a[2][bb-1]==1 && bb>1) ans++;//bb>1防止超出边界
    36             } else {
    37                 if(a[1][bb]==1) ans++;
    38                 if(a[1][bb+1]==1 && bb+1<=n) ans++;
    39                 if(a[1][bb-1]==1 && bb>1) ans++;
    40             }
    41             //如果这个点是由地面变成岩浆的话,之前算出来的ans就要更新
    42             //因为之前没有断路的地方现在可能会有断路
    43             if(ans==0) printf("Yes
    ");
    44             else printf("No
    ");
    45         }
    46     }
    47     return 0;
    48 }
    View Code

    这个代码不是很优秀,但是比较直观

    如果你已经理解的话,我们可以把代码进一步简化

    优化

    首先是空间上的优化,我们可以开一个2*1e5的数组,将原来的两行分别用k和!k表示,跟我们写的滚动数组方法类似

    其次我们可以不必要写太多判断,有些判断合并就可以

    最后我们可以删去一些不必要的头文件,再用一些位运算,使代码更加简洁高效

    代码

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int maxn=1e5+10;
     4 int a[2][maxn],q,ans=0,n,x,y;//ans记录不能联通的区域的个数
     5 int main(){
     6     scanf("%d%d",&n,&q);
     7     while(q--){
     8         scanf("%d%d",&x,&y);
     9         x--;//x--,方便以后的!运算 ,就是把原本的1和2变成了0和1
    10         a[x][y]^=1;//改变这个位置的状态 ,1^1=0,0^1=1
    11         int m=a[x][y]*2-1;//如果是0就是可以走,那结果就要减,1的话加 
    12         ans+=m*(a[!x][y-1]+a[!x][y]+a[!x][y+1]);//进行ans的累加 
    13         if(ans==0) printf("Yes
    ");
    14         else printf("No
    ");
    15     }
    16     return 0;
    17 }
    View Code

    比较

    时间上虽然差不多,但内存和长度减少了不少,看代码也更清晰

    最重要的是,这样写思维可以提升上去,不然那么容易过了也没什么意思

  • 相关阅读:
    Java web 例4-7
    JavaScript初步+基本函数
    请求转发和重定向区别
    javaben的设计规则
    Java web 实验五 Servlet过滤器
    关于软件生命周期以及软件过程
    Java web outTime.jsp
    Java web 4-6 update_stu_1.jps
    include指令与动作,请求妆发等同于forward动作
    简单的购物车应用案例 相关代码2
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/12634581.html
Copyright © 2011-2022 走看看