CF 1912 A NEKO's Maze Game

题目传送门

  • 题目描述

NEKO#ΦωΦ has just got a new maze game on her PC!

The game‘s main puzzle is a maze, in the forms of a 2×n2×n rectangle grid. NEKO‘s task is to lead a Nekomimi girl from cell (1,1)(1,1) to the gate at (2,n)(2,n) and escape the maze. The girl can only move between cells sharing a common side.

However, at some moments during the game, some cells may change their state: either from normal ground to lava (which forbids movement into that cell), or vice versa (which makes that cell passable again). Initially all cells are of the ground type.

After hours of streaming, NEKO finally figured out there are only qq such moments: the ii-th moment toggles the state of cell (ri,ci)(ri,ci) (either from ground to lava or vice versa).

Knowing this, NEKO wonders, after each of the qq moments, whether it is still possible to move from cell (1,1)(1,1) to cell (2,n)(2,n) without going through any lava cells.

Although NEKO is a great streamer and gamer, she still can‘t get through quizzes and problems requiring large amount of Brain Power. Can you help her?

  • 输入

The first line contains integers nn, qq (2≤n≤1052≤n≤105, 1≤q≤1051≤q≤105).

The ii-th of qq following lines contains two integers riri, cici (1≤ri≤21≤ri≤2, 1≤ci≤n1≤ci≤n), denoting the coordinates of the cell to be flipped at the ii-th moment.

It is guaranteed that cells (1,1)(1,1) and (2,n)(2,n) never appear in the query list.

  • 输出

For each moment, if it is possible to travel from cell (1,1)(1,1) to cell (2,n)(2,n), print "Yes", otherwise print "No". There should be exactly qq answers, one after every update.

You can print the words in any case (either lowercase, uppercase or mixed).

  • 样例

  • 样例输入

5 5
2 3
1 4
2 4
2 3
1 4

  • 样例输出

Yes
No
No
No
Yes

一句话题意: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

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

  • 代码

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=1e5+5;
int ans=0;
int a[3][maxn];
int main(){
    int n,q;
    scanf("%d%d",&n,&q);
    for(int i=1;i<=q;i++){
        int aa,bb;
        scanf("%d%d",&aa,&bb);
        if(a[aa][bb]==1){
            a[aa][bb]=0;
            if(aa==1){
                if(a[2][bb]==1) ans--;
                if(a[2][bb+1]==1 && bb+1<=n) ans--;
                if(a[2][bb-1]==1 && bb>1) ans--;
            } else {
                if(a[1][bb]==1) ans--;
                if(a[1][bb+1]==1 && bb+1<=n) ans--;
                if(a[1][bb-1]==1 && bb>1) ans--;
            }//如果这个点是由岩浆变成地面的话,之前算出来的ans就要更新
            //因为之前形成断路的地方现在不一定还有断路
            if(ans==0) printf("Yes\n");
            else printf("No\n");
        } else {
            a[aa][bb]=1;
            if(aa==1){
                if(a[2][bb]==1) ans++;
                if(a[2][bb+1]==1 && bb+1<=n) ans++;//bb+1<=n防止超出边界
                if(a[2][bb-1]==1 && bb>1) ans++;//bb>1防止超出边界
            } else {
                if(a[1][bb]==1) ans++;
                if(a[1][bb+1]==1 && bb+1<=n) ans++;
                if(a[1][bb-1]==1 && bb>1) ans++;
            }
            //如果这个点是由地面变成岩浆的话,之前算出来的ans就要更新
            //因为之前没有断路的地方现在可能会有断路
            if(ans==0) printf("Yes\n");
            else printf("No\n");
        }
    }
    return 0;
}

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

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

  • 优化

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

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

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

代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int a[2][maxn];
int main(){
    int q,ans=0,n;
    scanf("%d%d",&n,&q);
    int x,y;
    while(q--){
        scanf("%d%d",&x,&y);
        x--;//x--,方便以后的 ^ 运算
        a[x][y]^=1;//改变这个位置的状态
        int m=a[x][y]*2-1;//如果是 0 就是可以走,那结果就要减,1的话加
        ans+=m*(a[x^1][y-1]+a[x^1][y]+a[x^1][y+1]);//进行ans的累加
        if(ans==0)
            printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

  • 比较

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

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

CF 1912 A NEKO's Maze Game

原文地址:https://www.cnblogs.com/liuchanglc/p/12634581.html

时间: 2024-08-30 12:09:09

CF 1912 A NEKO's Maze Game的相关文章

Codeforces Round #614 (Div. 2) C. NEKO&#39;s Maze Game

题目链接:http://codeforces.com/contest/1293/problem/C 题意:给定n,q,即给定一个2*n的格子,有q个查询. 每个查询给定一个ri和ci,ri为1或2,ci在1到n之间,即给定一个(ri,ci),该点自该查询起状态进行转变(可经过/不可经过). 如某个查询给定1,2,即点(1,2)无法经过,若之后查询再次给定1,2,则该点(1,2)可以经过. 问能否从(1,1)走到(2,n),保证给定的查询不会经过起点和终点. 思路: 由于n和q最大都是1e5,所以

题解 CF1292A 【NEKO&#39;s Maze Game】

有一个结论: 当 \((1,1)\) 不能抵达 \((2,n)\) 时,必定存在一个点对,这两个点的值均为真,且坐标中的 \(x\) 互异,\(y\) 的差 \(\leq 1\) 这个结论的正确性感觉非常显然,就不多说了. 下图可以形象地解释点对的位置关系. 那对于每个点的值,只要开一个数组 f[i][j] 记录一下即可. 有了上述结论,我们记一个变量 \(cnt\) 表示 " 有多少对满足上述结论的点对 " ,则 \(cnt=0\) 时,\((1,1)\) 可以抵达 \((2,n)\

CodeForces 1292A NEKO&#39;s Maze Game(思维)

1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <

NEKO&#39;s Maze Game-cf

题意:给你一个2×n的矩阵,起点在左上,终点在右下,可以移动到本格相邻的格子里,给你q个时间点,每个时间点会有一个格子的状态发生变化,格子状态分为可走和不可走,一开始所以格子都是可走的,要求输出每个时间点能不能从起点走到终点. 思路:对任意格子来说,设它的坐标为x,y,对于他的另一行的三个坐标3-x,y-1  ,3-x,y和3-x,y+1有一个是不可走的,整个道路就被塞死了,就无法从起点走到终点.也就是说整个矩阵任意一个点满足这种关系,整条路走不通,所以我们统计整个矩阵有多少组这种关系设为num

#614 C. NEKO&#39;s Maze Game

起初一直看不懂题的意思,最后看了大佬的视频讲解才明白了题的意思. 题意:每次询问重复的时候抵消上一次操作  如果是奇数次的操作则视为障碍阻挡前进 收获:0和1的转换技巧,简单搜索和巧定义全局变量,没必要一定要写出来函数 非函数写法: #include<bits/stdc++.h> using namespace std; const int N=1e5+5; int a[2][N]; int main() { int n,q;int obstacle=0; cin>>n>&g

CF1293C - NEKO&#39;s Maze Game 分块

一定是两个障碍物组成一对来破坏连通性,每个障碍物可能属于最多3对,然后维护障碍物对数就行.但是懒得讨论,暴力分块过了. 涉及到修改的块暴力重构这个块的连通性.只要左端两个位置和右端两个位置中任意两个可互达就具有连通性. 然后每次询问,就先看每个块的连通性,再看每个块之间是否成功的连接起来. 1 #include <cstdio> 2 #include <cmath> 3 using namespace std; 4 int n,q,m,M,acc[1100],mp[3][11000

Codeforces Round #614 (Div. 2)

A. ConneR and the A.R.C. Markland-N 题目链接:https://codeforces.com/contest/1293/problem/A 题意: 有一个长为 n 的楼层,其中有 k 个楼层没有餐厅 ,你现在在 s 层,问你最少走多少个楼层可以到达餐厅吃饭 分析: 因为 k 只有 1000,所以直接往 s 层上下方找(当找到 0 或者 n + 1 时说明这个方向没有答案) #include<bits/stdc++.h> using namespace std;

Codeforces Round #614

NEKO's Maze Game 题意 题解 代码 Aroma's Search 题意 题解 代码 Xenon's Attack on the Gangs 题意 题解 代码 NEKO's Maze Game 题目链接 https://codeforces.com/contest/1292/problem/A 题意 给出一个 2xN 的地图,每一时刻都有一个位置翻转状态(可走和不可走变换),输出每时刻是否可以从起点走到终点. 题解 地图只有 2xN,两个跨行相邻的位置不可走从起点就走不到终点. [

Codeforces Round #554 (Div. 2) 1152C. Neko does Maths

学了这么久,来打一次CF看看自己学的怎么样吧 too young too simple 1152C. Neko does Maths 题目链接:"https://codeforces.com/contest/1152/problem/C" 题目大意:给你两个数a,b,现在要你找出一个数k使得(a+k)和(b+k)的最小公倍数最小. 题目思路:暴力(逃) 这题没得思路,想了想既然求LCM了那么和GCD说不定有点关系 然后就没有然后了 比赛的时候交了一发暴力上去,然并软 赛后补题,题解里面