首页 > 其他分享 >P7912 [CSP-J 2021] 小熊的果篮 题解

P7912 [CSP-J 2021] 小熊的果篮 题解

时间:2024-10-23 22:22:34浏览次数:8  
标签:q1 队列 end vis P7912 题解 start 2021 include

是模拟吗?

其实是的,虽然 $1 \le n \le 2 \times 10^5$,但是队列是个好东西.

我们定义一个结构体,来存放每一个块的信息,包括类型、起点、终点,将它们放入

队列当中,再使用基于广搜的思想,先处理,再合并,所以需要用到 $2$ 个队列.

注意点

数据中可能会有块的类型全是 $1$,或者全是 $0$ 的情况,所以保险起见,特判一下.

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>

using namespace std;

int n, a[200005], p;

struct node{
	int start, end, type; // 类型,起点,终点
};

// vis[i] 表示当前水果是否被取走
bool vis[200005];

queue<node> q, q1;

bool all_1() {
	for (int i = 1; i <= n; i++) {
		if (a[i] == 0) return 0;
	}
	return 1;
}

bool all_0() {
	for (int i = 1; i <= n; i++) {
		if (a[i] == 1) return 0;
	}
	return 1;
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
	if (all_1() || all_0()) { // 特判全是 1 或者 0 的情况
		for (int i = 1; i <= n; i++)
			printf("%d\n", i);
		return 0;
	}
	a[n+1] = 21474836; // 设下截止点
	int s = 1;
	for (int i = 2; i <= n + 1; i++) {
		if (a[i] != a[i-1]) { // 发现新的类型
			q.push((node){s, i - 1, a[i-1]}); // 存入
			s = i; // 更新起点
		}
	}
	int cnt = n; // 水果数量
	while (cnt) {
		while (!q.empty()) {
			node f = q.front();
			q.pop();
            // 找到当前能拿水果的起点
			while (vis[f.start] && f.start <= f.end) f.start++;
            // 出界了
			if (f.start > f.end) continue;
			printf("%d ", f.start);
			cnt--; // 水果数量减少
			vis[f.start] = 1; // 当前水果被拿走了
			if (f.start == f.end) continue; // 没有能拿的
			f.start++;
			q1.push(f); // 放入合并队列
		}
		printf("\n");
		node u;
		while (!q1.empty()) {
			u = q1.front();
			q1.pop();
			while (!q1.empty()) {
				node x = q1.front();
				if (u.type == x.type) { // 相同种类
					u.end = x.end; // 合并
					q1.pop();
				}
				else break; // 否则退出(只能合并相邻的2个)
			}
			q.push(u); // 存入新的块
		}
	}
	return 0;
}

标签:q1,队列,end,vis,P7912,题解,start,2021,include
From: https://www.cnblogs.com/panda-lyl/p/18498498

相关文章

  • P7071 [CSP-J2020] 优秀的拆分 题解
    二进制"优秀的拆分"如果存在,则代表$n$的二进制最低位不是$1$.$\because2^0=1$$\therefore$当$n$的二进制最低位为$1$时,不存在优秀的拆分.即$n$不是奇数.上述条件判断完后,就可以从$2$的$30$次方开始模拟(int的上限是$2^{31}-1$).代码#include<iostream>......
  • P7072 [CSP-J2020] 直播获奖 题解
    暴力使用$\Theta(n^2)$的时间复杂度来解决这题大约能拿到$60pts$.即枚举$p$,再枚举每个选手的分数.正解桶是个好东西.我们开一个桶,记录当前分数有多少人.然后计算获奖人数,分数从大到小进行枚举,直到当前人数$\ge$获奖人数.代码#include<iostream>#include<cstdio>#i......
  • [CSP-J2020] 表达式 题解
    短路这道题目中所含的运算符只有3个:与、或、非.在与运算和或运算中有2个性质.进行与运算时,若其中有一个值为0,则这个运算的结果就为0,即无需判断另1个数是否是0或1.进行或运算时,若其中有一个值为1,则这个运算的结果就为1,也无需判断另一个数是否是0或1.表达式树根据短路的性......
  • 题解 SS241023D【数颜色】/ ZROI3029【静态邻域数颜色】
    静态邻域数颜色-题目-ZhengruiOnlineJudge题目描述静态树上邻域数颜色。给一棵\(n\)个点的无根树,第\(i\)个点颜色为\(a_i\)。有\(q\)次询问,每次询问如下:给定\(x,d\),考虑所有距离\(x\)不超过\(d\)的点,求有多少种不同的颜色。形式化地,给定\(x,d\),求\(|\{a......
  • 题解 P5326【[ZJOI2019] 开关】/ SS241023B【判断题】
    已经沦落为可以随便搬进模拟赛的模板题了。。。题目描述当前有\(n\)道判断题,初始全选的错。初始给出每道题的正确答案,设\(0\)表示错,\(1\)表示对。每道题有一个参数\(p_i\),每轮会以\(\frac{p_i}{\sum_{j=1}^{n}p_j}\)的概率选择第\(i\)道题并修改(flip)这道题的答......
  • CVE-2021-27905(Apache Solr SSRF)漏洞复现
    CVE-2021-27905(ApacheSolrSSRF)ApacheSolr是一个开源的搜索服务,使用Java编写、运行在Servlet容器的一个独立的全文搜索服务器,是ApacheLucene项目的开源企业搜索平台。该漏洞是由于没有对输入的内容进行校验,攻击者可利用该漏洞在未授权的情况下,构造恶意数据执行SSRF攻击,......
  • [COCI2009-2010#4] PALACINKE 题解
    前言题目链接:洛谷。题意简述\(n\)个点,\(m\)条边。每条边上有商店,经过一条边花费\(1\)单位时间,如果在边上的商店购物,额外花费\(1\)单位时间。需要购买\(4\)种物品,每个商店售出\(1\sim4\)种物品不等。请问,在\(T\)个单位时间内,从\(1\)出发购物,得到这\(4\)种物品......
  • [算法题解] Codeforces round 979 --D. QED's Favorite Permutation
    题目链接:https://codeforces.com/contest/2030/problem/D题目:题解:FavotitePermutation即每个数满足i=p[i];此题中,p数组每次询问后保持不变,s根据询问而改变。因此每次需要进行交换的数的位置是相同的,只需要检验s变更后,操作能否满足交换需求与否。故创建需数组need,预处理nee......
  • 题解:CF1225E Rock Is Push
    很玄妙的一道dp题。HintAnalysis首先你要确保你会做当石头没有/固定的情况,这道题其实也是dp。考虑石头带来的影响,唯一的作用就是限制你的移动,比方说你下面有\(3\)块石头,由于只能向右或向下移动,你实际上往下只能走到当前列第\(n-3\)行。于是对于石头的处理,设\(rs[i][j......
  • 题解:P11215 【MX-J8-T3】水星湖
    依旧是模拟赛赛题。HintAnalysis首先你注意到两棵相邻的树是一定不会死的,所以可能会死的只有自己种下去的树,队列维护。接着考虑对于每个位置,\(\text{bfs}\)维护一个最小的长出树的时间\(vis[i][j]\),最后暴力统计答案即可。具体细节看注释。Code#include<bits/stdc++.h>......