【CCF-CSP】202403-4 十滴水

题目描述

十滴水是一个非常经典的小游戏。

img

小 C 正在玩一个一维版本的十滴水游戏。我们通过一个例子描述游戏的基本规则。

游戏在一个 1×c 的网格上进行,格子用整数x(1≤x≤c) 编号,编号从左往右依次递增。网格内 m 个格子里有 1∼41∼4 滴水,其余格子里没有水。在我们的例子中,c=m=5,按照编号顺序,每个格子中分别有 2,4,4,4,22,4,4,4,2 滴水。

玩家可以进行若干次操作,每次操作中,玩家选择一个有水的格子,将格子的水滴数加一。任何时刻若某个格子的水滴数大于等于 55,这个格子里的水滴就会向两侧爆开。此时,这个格子的水被清空,同时对于左方、右方两个方向同时进行以下操作:找到当前格子在对应方向上最近的有水的格子,如果存在这样的格子,将这个格子的水滴数加一。若在某个时刻,有多个格子的水滴数大于等于 55,则最靠左的先爆开。

在我们的例子中,若玩家对第三格进行操作,则其水滴数变为 55,故第三格水滴爆开,水被清空,其左侧最近的有水格子(第二格)和右侧最近的有水格子(第四格)的水量增加 11,此时每个格子中分别有 2,5,0,5,22,5,0,5,2 滴水。

此时第二格和第四格的水滴数均大于等于 55,按照规则,第二格的水先爆开,爆开后每个格子中分别有 3,0,0,6,23,0,0,6,2 滴水;最后第四格的水滴爆开,每个格子中分别有 4,0,0,0,34,0,0,0,3 滴水。

小 C 开始了一局游戏并进行了 n 次操作。小 C 在每次操作后,会等到所有水滴数大于等于 55 的格子里的水滴都爆开再进行下一次操作。

小 C 想知道他的水平有多高,于是他想知道每一次操作后还有多少格子里有水。

保证这 n 次操作都是合法的,即每次操作时操作的格子里都有水。

输入格式

从标准输入读入数据。

输入的第一行三个整数c,m,n 分别表示网格宽度、有水的格子个数以及操作次数。

接下来 m 行每行两个整数x,w,表示第 x 格有 w 滴水。

接下来 n 行每行一个整数 p,表示小 C 对第 p 格做了一次操作。

输出格式

输出到标准输出。

输出 n 行,每行一个整数表示这次操作之后网格上有水的格子数量。

思路

通过读题,可以发现,对一个格子进行操作,增加一滴水,如果爆的话只会影响到左右两个点,左右两个点如果再爆的话又会影响他们的左右点。每个点都是这样,只会影响到左右两个点,也就是前驱和后继。因此,可以考虑用静态链表来处理,记录每个点的前驱和后继。

c的范围很大,1e9,但是m只有3x1e5,而且题目中说了只会选择有水的格子进行操作,也就是在这m个格子里面选。因此,只要存储这m个格子就够了,再排序一下,用pre和nxt记录每个格子的前驱和后继。

然后每次操作,我们把大于等于5的格子放到优先队列里(优先队列:优先爆左,下标的小根堆),把这个格子从链表里删去,再对前驱和后继进行加一滴水,如果大于等于5就加入队列,依次处理队列里的格子就好了。

代码

#include <bits/stdc++.h>
#define N 300005
using namespace std;

int c,n,m,p,vis[N];
map<int,int> idx;

struct node{
	int p,w;//位置,水滴数量,
	int pre,nxt;//前驱,后继
	bool operator < (const node &b) const{//按位置升序
		return p<b.p;
	}
}a[N];

int main(){
	cin>>c>>m>>n;
	for(int i=1;i<=m;i++){
		cin>>a[i].p>>a[i].w;
	}
	sort(a+1,a+1+m);
	for(int i=1;i<=m;i++){//静态链表预处理
		a[i].pre=i-1,a[i].nxt=i+1;
		idx[a[i].p]=i;
	}
	int ans=m;
	priority_queue<int,vector<int>,greater<int> > q; 
	for(int i=1;i<=n;i++){
		cin>>p;
		int id=idx[p];
		a[id].w+=1;//水滴数加1
        //用vis标记之前有没有爆过,没有爆且水滴数>=5,就加入队列
		if(a[id].w>=5&&!vis[id]) q.push(id),vis[id]=1; 
		while(q.size()){
			ans--;
			id=q.top();//最左边的先爆
			q.pop();
			int pre=a[id].pre,nxt=a[id].nxt;
//			cout<<"##"<<id<<" "<<pre<<" "<<nxt<<endl;
			a[pre].nxt=nxt;//更新静态链表
			a[nxt].pre=pre;
			if(pre>=1){//前驱
				a[pre].w+=1;
				if(a[pre].w>=5&&!vis[pre]) q.push(pre),vis[pre]=1;
			}
			if(nxt<=m){//后继
				a[nxt].w+=1;
				if(a[nxt].w>=5&&!vis[nxt]) q.push(nxt),vis[nxt]=1;
			}
		}
		cout<<ans<<endl;
	}
	
	return 0;
}

<think>好的,我现在需要回答用户关于CCF-CSP比赛规则或赛制的问题。用户已经提供了四个引用来源,我需要仔细分析这些信息,并整理出一个结构清晰的回答。 首先,我要确认用户的问题核心是CCF-CSP的赛制规则,可能包括认证级别、考试内容、评分规则、认证时间和形式等方面。接下来,我需要从提供的引用中找到相关信息。 引用[1]提到CCF CSP认证是计算机软件能力认证,属于职业资格认证。引用[2]指出CSP-J/S分两个级别,不设年龄限制,面向非专业级。引用[3]补充了CSP-JS分为入门组和提高组,涉及算法和编程,并且提到了GESP一级认证的情况。引用[4]则强调了需要扎实的基础知识和实践经验,无论是个人还是团队参赛。 接下来,我需要将这些信息整合成几个关键点。比如,认证级别分为CSP-J和CSP-S,考试内容可能包括算法和编程题,评分规则可能涉及题目得分和等级评定,认证时间可能每年举办,形式为机试。 需要注意的是,用户提供的引用中没有详细的评分细则,比如每题分值或通过标准,所以可能需要说明具体评分规则需参考当年公告。同时,引用[2]提到了第二轮认证,可能说明赛制分为初赛和复赛,但需要确认是否适用于所有级别的认证。 另外,引用[3]提到了GESP Python认证一级,这可能与CSP不同,但用户问题集中在CSP上,所以可以暂时忽略这部分,除非有直接关联。 整理时还要确保回答结构清晰,分点列出,并自然地添加引用标识。最后,生成的相关问题需要与CCF-CSP的赛制相关,比如认证难度、备考方法、与其他竞赛的区别等。 现在需要检查是否有遗漏的信息或可能的错误。例如,引用[2]提到CSP-J/S2020第二轮认证,可能意味着CSP-J/S分为两轮,但引用[4]没有明确说明,因此需要谨慎表述,指出通常分为两轮,但具体以官方公告为准。 总结下来,回答应包含以下几个部分:认证级别、考试内容、评分规则、认证时间和形式,以及注意事项。每个部分引用对应的来源,并在末尾生成相关问题。</think>### CCF CSP比赛规则与赛制详解 #### 1. **认证级别与分组** CCF CSP认证分为**非专业级别(CSP-J/S)**和**专业级别**。其中: - **CSP-J(入门组)**:面向算法和编程基础较弱的初学者。 - **CSP-S(提高组)**:面向有一定编程和算法能力的学习者[^3]。 - 专业级别认证(如GESP)则针对更高级别的编程能力评估,例如Python一级认证等[^3]。 #### 2. **考试内容** - **题型**:以算法和编程题为主,涵盖数据结构、动态规划、图论等计算机科学核心内容。 - **形式**:上机编程,需在限定时间内完成题目并提交代码[^4]。 - **难度分级**:CSP-J题目相对基础,CSP-S题目复杂度更高,涉及更深入的算法设计。 #### 3. **评分规则** - **得分机制**:每题按测试用例通过比例得分,例如某题有10个测试点,通过6个则得60%分数[^2]。 - **等级评定**:根据总分划分等级(如A/B/C),具体分数线由CCF官方在考试后公布[^2][^4]。 #### 4. **认证时间与形式** - **频率**:每年举办多轮认证,例如CSP-J/S通常分为初赛和复赛两轮。 - **初赛**:多为笔试或在线理论考试,筛选进入复赛的选手。 - **复赛**:上机编程实践,决定最终成绩[^4]。 #### 5. **参赛资格与注意事项** - **资格**:无年龄、职业限制,学生和在职人员均可报名。 - **团队参赛**:部分赛事允许团队协作,但需遵守具体规则[^4]。 - **认证用途**:CSP成绩可作为高校录取、企业招聘的参考依据[^1]。 #### 注意事项 - 具体赛制可能因年份调整,需以**CCF官方公告**为准。 - 编程语言通常支持C++、Java、Python等,需提前确认环境要求。 --- ###
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值