首页 > 其他分享 >JEOI-R1:棋

JEOI-R1:棋

时间:2022-12-03 15:24:07浏览次数:34  
标签:le R1 int 询问 位置 矩阵 棋子 JEOI

「JEOI-R1棋

题目前言

巨大诈骗题

题面

题目描述

现在有一个 \(n\times m\) 的棋盘,从上到下依次是 \(1\sim n\) 行,从左到右依次是 \(1\sim m\) 列,一个位于第 \(x\) 行第 \(y\) 列的位置被标记为 \((x,y)\)。共有 \(c\) 个棋子,不重叠地摆放在棋盘的某些位置上。一个位于 \((x,y)\) 的棋子可以走向 \((x-1,y-1),(x-1,y+1),(x+1,y-1),(x+1,y+1)\)(如果这些位置存在且其上没有棋子)。

现有若干询问,每次询问给定 \(x_1,y_1,x_2,y_2,p\),然后给定 \(p\) 个位置,表示一个子矩阵的左上角位置为 \((x_1,y_1)\),右下角位置为 \((x_2,y_2)\),问是否可以移动棋子(无次数限制)使得矩阵内有且仅有给定的 \(p\) 个位置上有棋子。询问之间相互独立。

为了减少程序时间复杂度的常数影响,建议使用更快的读入方式。

输入格式

第一行三个正整数 \(n,m,c\),表示棋盘的列数、行数和已有的棋子数。

接下来 \(c\) 行,一行两个整数 \(a_i,b_i\),表示有一个棋子位于 \(a_i\) 行 \(b_i\) 列处。

接下来一行一个正整数 \(q\)。

接下来 \(q\) 组询问。每一组询问第一行是五个正整数 \(x_1,y_1,x_2,y_2,p\),接下来 \(p\) 行每行两个正整数 \(c_i,d_i\),表示只希望矩阵内有棋子的位置。

输出格式

对于每个询问,如果可以移动棋子(无次数限制)使得矩阵内有且仅有给定的位置上有棋子,输出 YES,否则输出 NO

样例 #1

样例输入 #1

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

样例输出 #1

NO
YES
NO

@ 提示

【样例解释 #1】

解释以 0 代表空位,1 代表放置了棋子的位置。

初始状态:

011
100
011

对于第一个询问,可以证明 \((1,2)\) 处的棋子无法移出 \((1,2)\) 到 \((2,3)\) 的矩阵。

对于第二个询问,考虑把 \((3,2)\) 处的棋子移到 \((2,3)\),得:

011
101
001

满足询问要求。移动方式不唯一。

对于第三个询问,可以证明 \((2,1)\) 处的棋子无法移出 \((1,1)\) 到 \((2,3)\) 的矩阵。

【数据范围】

对于 \(25\%\) 的数据,\(n,m,q\le 10\),\(c\le 20\)。

对于另外 \(25\%\) 的数据,保证 \(a_i+b_i\equiv 0 \pmod 2\),\(c_i+d_i\equiv 0 \pmod 2\)。

对于另外 \(25\%\) 的数据,保证 \(n\cdot m-c\le(x_2-x_1+1)\cdot (y_2-y_1+1)-p\)。

对于 \(100\%\) 的数据,\(2\le n,m\le 10^5\),\(1\le c,q\le 10^5\),\(c\le n\cdot m\),\(1\le a_i\le n\),\(1\le b_i\le m\),\(\sum p\le 2\times 10^5\)。对于每个询问,\(1\le p\le (x_2-x_1+1)\cdot (y_2-y_1+1)\),\(x_1\le c_i\le x_2\),\(y_1\le d_i\le y_2\)。

【提示与说明】

提供一种较快的读入一个 int 类型非负整数的方式。调用下文中的 read(),其作用是返回输入中的一个非负整数,同时读取其后的一个字符。

int read() {
  int x(0);
  char c(getchar());
  while (c < '0' || c > '9') c = getchar();
  while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
  return x;
}

题解

巨大诈骗题

首先看着移动方式:

棋子可以走向 \((x-1,y-1),(x-1,y+1),(x+1,y-1),(x+1,y+1)\)

不难发现,更改后的\(x',y'\)满足:\(x'+y'\equiv x+y (\bmod 2)\),这启发我们分奇偶性讨论这个问题
以下称一类格为横纵坐标之和为奇的格子,零类格为横纵坐标之和为偶的格子

引理 :
一个棋子可以到达棋盘上与其同类的格子

由移动前后奇偶性不变可得必要性,现在来证明充分性。

本题的棋子移动数量不限,则可以以一种延迟撤回的思想,即由这个棋子往目标方向跳,若有撞上的则将撞上的移开,若撞上的那个棋子无路可走,则又移动撞上的那个棋子的周围棋子,如此类似递归步骤,可知这个棋子无论如何可以被移开。故充分性得证。

那么本题做法就比较明显了:先预处理出原矩阵\((1,1,n,m)\)中零一类点个数分别记为\(Q_0,Q_1\),将零一类棋子数量分别记为\(S_0,S_1\)。对于每一次输入的待求矩阵,统计出它总共的零一类点的个数为\(T_0,T_1\),并求出需要移动棋子到达的位置(对应\(c_i,d_i\))中零一类位置有\(P_0,P_1\)个,则这个问题有解的充要条件为:

\[\left\{ \begin{aligned} P_0&\le S_0 \\ P_1&\le S_1 \\ \end{aligned} \right. \]

\[\left\{ \begin{aligned} S_0-P_0\le Q_0-T_0\\ S_1-P_1\le Q_1-T_1\\ \end{aligned} \right. \]

然后我们讨论对于这些变量的求法。首先若\(nm\)为偶数,那么\(Q_0,Q_1\)就都等于\(\frac{nm}{2}\),否则\(Q_0=\left\lceil\frac{nm}{2}\right\rceil,Q_1=nm-Q_0\)(第一个出现的是\((1,1)\),属于零类点。)

而对于\(T_0,T_1\)的计算方式类似于\(Q_0,Q_1\),记\(l=x_2-x_1+1,r=y_2-y_1+1\),若\(lr\equiv 0 (\bmod 2)\)则平分,否则先将\(T_0,T_1\)全部赋值为\(\left\lfloor\frac{lr}{2}\right\rfloor\),然后根据\((x_1,y_1)\)所属哪一类点,则将所对应的\(T\)加上\(1\)。至于\(S_0,S_1,P_0,P_1\)就没得说了,非常简单。

十年OI一场空,不开longlong见祖宗

#include<iostream>
#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;
int n,m,t1,t0,p,q0,q1,s1,s0,a,b,c,d;
int read() {
  int x(0);
  char c(getchar());
  while (c < '0' || c > '9') c = getchar();
  while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
  return x;
}

signed main(){
	n=read(),m=read(),c=read();
	q1=n*m/2,q0=n*m-q1;
	for(int i=1;i<=c;i++){
		int x=read(),y=read();
		if((x+y)&1)s1++;
		else s0++; 
	}
	int t=read();
	while(t--){
		int x1=read(),y1=read(),x2=read(),y2=read();
		int l=x2-x1+1,r=y2-y1+1,p0=0,p1=0;
		if((l*r)&1){
			if((x1+y1)&1){
				t0=l*r/2;
				t1=l*r-t0;
			}
			else {
				t1=l*r/2;
				t0=l*r-t1;
			}
		}
		else {
			t1=l*r/2;
			t0=l*r/2;
		}
		int q=read();
		for(int i=1;i<=q;i++){
			int x=read(),y=read();
			if((x+y)&1)p1++;
			else p0++;
		} 
		if(p0<=s0&&p1<=s1&&(s0+t0)<=(q0+p0)&&(s1+t1)<=(q1+p1))puts("YES");
		else puts("NO");
	}
}

标签:le,R1,int,询问,位置,矩阵,棋子,JEOI
From: https://www.cnblogs.com/oierpyt/p/16947743.html

相关文章

  • 攻防世界 XSCTF 联合招新赛 QR1
    一张空白的图片?图片宽高都很大,默认比例下看着像空白的,但放大之后能看到一个个小点。转成PNG或者JPG,导入PhotoShop之后拉阈值就能看到完整二维码了,扫码获得flag......
  • 【题解】 P8287 「DAOI R1」Flame
    题面传送门解决思路本题解是对这篇题解部分内容的补充,讨论的是两种\(\mathcal{O(m\logn)}\)的做法。大体思路都是一样的,先预处理出每一条边需要多少时间后才能连......
  • Initializing ExecutorService 'getCrawler1'
    程序执行一直卡在:InitializingExecutorService  去掉idea的断点   ......
  • 联想小新Air14使用傲梅分区助手进行硬盘克隆出现的问题,克隆完显示RAW格式解决方案,win1
    联想小新Air14使用傲梅分区助手进行硬盘克隆出现的问题,克隆完显示RAW格式解决方案买电脑时没考虑到512会不够用,也没注意到小新Air14是单插槽的,所以有了今天的故事。本文......
  • mycompiler1 大学生利用C++构建一个编译器之词法分析器
    文章目录​​1.定义语言​​​​2.编译器工作流程​​​​2.1.编译器处理的两大过程和分层设计​​​​3.词法分析器的实现​​​​3.1.有限状态机(正则匹配)​​​​3......
  • MBR10200AC-ASEMI肖特基二极管MBR10200AC
    编辑-ZMBR10200AC在TO-220AC封装里采用的1个芯片,其尺寸都是86MIL,是一款大功率肖特基二极管。MBR10200AC的浪涌电流Ifsm为150A,漏电流(Ir)为0.05mA,其工作时耐温度范围为-65~17......
  • MBR10200AC-ASEMI肖特基二极管MBR10200AC
    编辑-ZMBR10200AC在TO-220AC封装里采用的1个芯片,其尺寸都是86MIL,是一款大功率肖特基二极管。MBR10200AC的浪涌电流Ifsm为150A,漏电流(Ir)为0.05mA,其工作时耐温度范围为-65~......
  • FR11 webservice程序数据集
    packagecom.fr.data;importcn.hutool.core.lang.Console;importcn.hutool.http.webservice.SoapClient;importcn.hutool.json.JSONArray;importcn.hutool.json.......
  • 夏日友晴人 chapter1
    "Aaaaaaaahhhh!"Thescreamdidn'tcomefromacoupleoffrightenedfishermen.Itcamefromtheoceandepths.Specifically,fromthemouthofthirteen-year-olds......
  • MBR16200CT-ASEMI插件肖特基二极管MBR16200CT
    编辑-ZMBR16200CT在TO-220AB封装里采用的2个芯片,其尺寸都是102MIL,是一款插件肖特基二极管。MBR16200CT的浪涌电流Ifsm为200A,漏电流(Ir)为0.05mA,其工作时耐温度范围为-65~175......