[CSP-S模拟测试]:Emotional Flutter(贪心)

题目传送门(内部题51)


输入格式

第一行一个整数$t$表示数据组数。
每组数据的第一行有三个整数$s,k,n$。
第二行有$n$个整数$A_1,A_2,...,A_n$,依次表示黑白条的长度。


输出格式

若能通过输出$"TAK"$,否则输出$"NIE"$。


样例

样例输入:

2
2 8 7
2 5 6 3 2 1 2
2 8 4
1 6 7 4

样例输出:

TAK
NIE


数据范围与提示

样例解释:

数据范围:

$30\%$的数据,$n\leqslant 1300$;
$50\%$的数据,$n\leqslant 22,000$;
$100\%$的数据,$2\leqslant n\leqslant 500,000,1\leqslant s<k\leqslant {10}^9,1\leqslant A_i\leqslant {10}^9,1\leqslant t\leqslant 10$。
数据有梯度。输入文件较大请使用读入优化。


题解

其实就是一个贪心,主要是策略很难想。

首先来处理脚的长度,我们可以将所有的黑块都延长$s$,所有的白块左端点向右移动$s$,这样就相当与忽略了脚的长度。

然后会有一些特判的情况,对于我的贪心策略,我们只需要用到当一个黑块长度大于$k$时,肯定跳不过去,所以直接输出$"NIE"$即可。

现在来讲对于一般情况,我是如何判断的。

首先,将所有的黑块的左端点和右端点分别$\mod k$,那么我们是不能在这段区间进行起跳的;如果出现$\mod k$完之后右端点小于左端点,那么区间$[0,r]$和区间$[l,k-1]$是不能起跳的。

之后我们只需要将所有的不能跳的区间排个序,然后我们只需要找到一个可以起跳的点即可。

细节比较多,慢慢调吧……

时间复杂度:$\Theta(n\log n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
struct rec{long long l,r;}e[10000000];
long long s,k,n;
long long sum[5000001];
long long lft[5000001],rht[5000001],wsq;
int top;
bool flag;
bool cmp(rec a,rec b){return a.l==b.l?a.r<b.r:a.l<b.l;}
int main()
{
	int T;scanf("%d",&T);
	while(T--)
	{
		scanf("%lld%lld%lld",&s,&k,&n);
		top=flag=wsq=0;
		for(int i=1;i<=n;i++)
		{
			long long a;
			scanf("%lld",&a);
			if(i&1)a+=s;
			else{a-=s;a%=k;}
			if(a>k)flag=1;
			sum[i]=sum[i-1]+a;
			if(i&1)
			{
				lft[i]=sum[i-1]+1;
				rht[i]=sum[i]-1;
			}
		}
		if(((n&1)&&sum[n]<=k)||((!(n&1))&&sum[n-1]<=k)){puts("TAK");continue;}
		if(flag){puts("NIE");continue;}
		for(int i=1;i<=n;i+=2)
		{
			lft[0]=lft[i]%k;
			rht[0]=rht[i]%k;
			if(rht[0]<lft[0])
			{
				e[++top]=(rec){0,rht[0]};
				e[++top]=(rec){lft[0],k-1};
			}
			else e[++top]=(rec){lft[0],rht[0]};
		}
		sort(e+1,e+top+1,cmp);
		if(e[1].l){puts("TAK");goto nxt;}
		for(int i=1;i<=top;i++)
		{
			if(wsq+1<e[i].l){puts("TAK");goto nxt;}
			wsq=max(wsq,e[i].r);
		}
		if(wsq<k-1){puts("TAK");continue;}
		puts("NIE");
		nxt:;
	}
	return 0;
}


rp++

原文地址:https://www.cnblogs.com/wzc521/p/11569467.html

时间: 2024-11-09 14:30:24

[CSP-S模拟测试]:Emotional Flutter(贪心)的相关文章

csp-s模拟47 Emotional Flutter,Endless Fantasy题解

题面:https://www.cnblogs.com/Juve/articles/11558523.html A:Emotional Flutter 如果起点确定,那么我们后面走的点都是固定的,及mod k余数相同 如果路径中有一个%k在黑块里,那么这个起点是不可行的 然后我们可以对于所有黑块,看它限制了哪些余数 最后我们要判断的就是有没有一个长度为s的连续区间,使得它没有被限制 #include<iostream> #include<cstdio> #include<alg

[CSP-S模拟测试]:赛(贪心+三分)

题目描述 由于出题人思维枯竭所以想不出好玩的背景.有$n$个物品,第$i$个物品的价格是$v_i$,有两个人,每个人都喜欢$n$个物品中的一些物品.要求选出正好$m$个物品,满足选出的物品中至少有$k$个物品被第一个人喜欢,$k$个物品被第二个人喜欢.并求出最小的价格和. 输入格式 第一行三个数$n,m,k$.第二行$n$个数,第$i$个数表示$v_i$.第三行包含一个数$a$,表示第一个人喜欢的物品数.第四行包含$a$个数,表示第一个人喜欢的物品是哪几个.第五行包含一个数$b$,表示第二个人喜

[CSP-S模拟测试]:Tree(贪心)

题目描述 给定一颗$n$个点的树,树边带权,试求一个排列$P$,使下式的值最大 $$\sum \limits_{i=1}^{n-1}maxflow(P_i,P_{i+1})$$ 其中$maxflow(s,t)$表示从点$s$到点$t$之间的最大流,即从$s$到$t$的路径上最小的边权 输入格式 第一行一个整数$n$,表示点数下接$n−1$行,每行三个数$u,v,w$表示一条连接点$u$和点$v$权值为$w$的边 输出格式 输出一行一个整数,表示答案 样例 样例输入: 21 2 2333 样例输出

[CSP-S模拟测试]:d(贪心+树状数组)

题目传送门(内部题65) 输入格式 第一行,一个自然数$T$,代表数据组数.对于每组数据:第一行,一个正整数$n$,一个自然数$m$.接下来$n$行,每行两个正整数,$a_i,b_i$. 输出格式 对于每组数据,输出一行,一个整数,代表答案. 样例 样例输入: 3 2 0 5 10 5 5 2 1 1 1 2 2 3 1 3 5 4 4 5 3 样例输出: 25412 数据范围与提示 保证$0\leqslant m<n,a_i,b_i\leqslant 10^5$. 题解 题目并不难,考虑贪心,

[CSP-S模拟测试]:优化(贪心+DP)

题目描述 $visit\text{_}world$发现有下优化问题可以用很平凡的技巧解决,所以他给你分享了这样一道题:现在有长度为$N$的整数序列$\{ a_i\}$,你需要从中选出$K$个不想叫的连续子区间(可以存在元素不被选),从左到右记它们的和为$s_1,s_2,...,s_k$,我们的优化目标是最大化下述和式:$$\sum \limits_{i=1}^{k-1}|s_i-s_{i+1}|$$你只需要输出这个最大的和即可. 输入格式 第一行两个整数$N,K$,意义如上.接下来一行$N$个整

[CSP-S模拟测试]:爬(贪心)

题目传送门(内部题134) 输入格式 第一行两个数$N,L$. 接下来$N$行每行两个数$A_i,B_i$. 接下来$N$行每行一个整数$C_i$. 输出格式 一行一个整数表示答案,无解输出$-1$. 样例 样例输入1: 3 96 35 23 1222 样例输出1: 2 样例输入2: 5 203 24 26 38 410 542345 样例输出2: -1 数据范围与提示 对于$40\%$的数据,$N\leqslant 1,000$: 对于额外$20\%$的数据,$B_i=0$: 对于额外$20\

2018冬令营模拟测试赛(三)

2018冬令营模拟测试赛(三) [Problem A]摧毁图状树 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见"试题描述" 输出示例 见"试题描述" 数据规模及约定 见"试题描述" 题解 这题没想到贪心 QwQ,那就没戏了-- 贪心就是每次选择一个最深的且没有被覆盖的点向上覆盖 \(k\) 层,因为这个"最深的没有被覆盖的点"不可能再有其它点引出的链覆盖它了,而它又

2018冬令营模拟测试赛(十九)

2018冬令营模拟测试赛(十九) [Problem A]小Y 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见"试题描述" 输出示例 见"试题描述" 数据规模及约定 见"试题描述" 题解 目前未知. 这题目前就能做到 \(O(n \sqrt{M} \log n)\),其中 \(M\) 是逆序对数,然而会被卡 \(T\):当然这题暴力可以拿到和左边那个算法一样的分数,只要暴力加一个剪枝:当左

2019.9.19 csp-s模拟测试47 反思总结

思路接近正解?都想到了?这都是借口呀. 没有用的,往前走吧. T1:Emotional Flutter 我的做法和题解不太一样,我把s放在最后考虑了. 因为出发以后步幅是一样的,所以每一个黑条可以ban掉一段出发点.把黑条的左右边界%k存成区间,每个黑条可以存一个或者两个区间[跨越k这个边界].然后像以前写区间覆盖的贪心一样按左端点排序,看看有没有长至少为s的空余. 代码: #include<iostream> #include<cstdio> #include<cstrin