2020.03.25【NOIP普及组】模拟赛C组20

题目编号 标题
0 公鸡打鸣(rooster)
1 拯救小鸡(chicken)
2 母鸡下蛋(hen)
3 鸡国福利(kingdom)

T1:

题目描述

鸡国中有两只最喜欢打鸣的公鸡 G1 和 G2,它们每一次打鸣都有一个声音的响度值。一天清晨,G1 开始先开始打鸣,响度值为 x,G2 听到 G1 的打鸣后也开始打鸣,响度值为 y。G1 和 G2 很想把它们打鸣声音的响度值调成一样。所以它们进行了 k 次协商,每一次协商后就各自增加或减少一定的响度值再打鸣一次(打鸣的响度值不能小于 0)。G1 和 G2 生性迟钝,它们不知道其实经过 s(s≤k)次协商后,打鸣声音的响度值已经相同了。请编程帮 G1 和 G2 计算一下它们打鸣声音的响度值相同时最少经过了几次协商(即最小的 s)?
注意:如果 x 一开始就等于 y,则不需要协商。

输入

输入共 k+1 行。
第 1 行三个整数 x,y 和 k,分别表示 G1、G2 第一次打鸣时声音的响度值,共进行了 k次协商并调整打鸣声音的响度值。
接下来 k 行,每行包含 4 个整数 ai,xi,bi,yi,表示第 i 次协商 G1 增加(ai等于 1)或减少(ai等于-1)的响度值为 xi,G2 增加(bi等于 1)或减少(bi等于-1)的响度值 yi。

输出

输出 1 行一个整数,表示至少经过多少次协商后 G1 和 G2 的打鸣响度值已经相同。如果经过 k 次协商后仍然无法相同,则输出“-1”(不包含双引号)。

样例输入

Input1:
2 3 3
1 1 -1 0
-1 1 1 1
1 1 -1 1
Input2:
2 3 4
1 2 -1 2
-1 1 1 1
-1 4 1 1
1 4 1 1
Input3:
2 3 1
1 2 -1 2

样例输出

Output1:
1
Output2:
4
Output3:
-1

数据范围限制

提示
Sample1:
在样例 1 中,G1 和 G2 第 1 次打鸣的响度值分别为 2 和 3,不相同。第 1 次协商 G1 增加 1,G2 减少 0,响度值分别为 3 和 3,所以经过 1 次协商后它们两个打鸣的响度值已经相同。经过 3 次协商时,它们的声音也能调成一样,但至少需要 1 次协商就可以了。

Sample2:
在样例 2 中,G1 和 G2 第 1 次打鸣的响度值分别为 2 和 3,不相同。第 1 次协商后打鸣的响度值分别为 4 和 1,第 2 次协商后打鸣的响度值分别为 3 和 2,第 3 次协商后打鸣的响度值分别为 0(不能小于 0)和 3,第 4 次协商后打鸣的响度值分别为 4 和 4, 所以经过 4 次协商后它们两个打鸣的响度值相同。

Sample3:
在样例 3 中,G1 和 G2 第 1 次打鸣的响度值分别为 2 和 3,不相同。第 1 次协商 G1 增加 2,G2 减少 2,响度值分别为 4 和 1,所以经过 1 次协商后它们两个打鸣的响度值仍然无法相同,则输出“-1”。

这题非常简单

#include
#include
using namespace std;
long long x,y;
int k;
int ans,f;
int main(){
	freopen("rooster.in","r",stdin);
	freopen("rooster.out","w",stdout);
	cin>>x>>y>>k;
	if(x==y){
		ans=0;
		f=1;
	}
	int i=0;
	while(k--){
		i++;
		int ai,xi,bi,yi;
		scanf("%d%d%d%d",&ai,&xi,&bi,&yi);
		if(ai==1){
			x+=xi;
		}
		else{
			x-=xi;
		}
		if(bi==1){
			y+=yi;
		}
		else{
			y-=yi;
		}
		if(x<0)x=0;
		if(y<0)y=0;
		if(x==y&&f!=1){
			f=1;
			ans=i;
		}
	}
	if(f==0)cout<<-1;else
	cout<<ans;
	return 0;
}

T2:

题目描述

鸡国最近遇到了一件很棘手的事情,经常有一只老鹰想来抓小鸡。经鸡国情报员探查,这只老鹰打算共来袭击 n 次,第 i 次来的时刻为第 ti(1≤i≤n) 秒时刻。
鸡国国王为了保护鸡国中的小鸡,决定派出鸡国警察(鸡国有无穷多个警察)来巡逻。每个警察巡逻的时间长度都为 t 秒。当老鹰来袭击的时刻至少要有 x 名警察才能抵御老鹰的袭击。另外国王派遣警察有两个原则:
(1)每个时刻最多只能派遣一名警察。在第 0 秒时刻及第 0 秒之前的时刻(鸡国有负数时刻)也可以事先准备派遣警察,但每个时刻最多也只能派遣一名警察。
(2)延迟 1 秒执行巡逻任务。第 i 秒时刻派遣的警察,在第 i+1 到 i+t 秒时刻执行巡逻任务。
为帮助国王节省开支,请帮忙计算至少需要派遣多少名警察才能保证鸡国小鸡不被老鹰抓走?

输入

输入共 2 行。
第 1 行输入三个整数n,t,x,分别表示老鹰总共袭击次数,每个警察巡逻的时间长度,以及某个时刻能抵挡住老鹰袭击的最少警察数量。
第 2 行 n 个严格升序排列的正整数 ti(1≤i≤n),表示第 ti秒时刻老鹰会发动袭击。

输出

输出 1 行一个整数,表示总共至少需要派遣多少个警察才能抵御老鹰的 n 次袭击,如果出现无法抵御老鹰的袭击时,输出“-1”(不包含双引号)。

样例输入

Input1:
3 3 3
2 3 4
Input2:
1 2 3
3

样例输出

Output1:
5
Output2:
-1

数据范围限制

提示

Sample1:
样例 1 中,老鹰来袭击 3 次,分别在第 2,3,4 秒时刻,每个警察的巡逻时间为 3 秒,当老鹰来袭击时至少要有 3 名警察才能抵御老鹰的袭击。首先可以在第-1,0,1 秒三个时刻分别派遣一名警察,抵御老鹰第 2 秒时刻的袭击,然后再在第 2 秒时刻派遣一名警察,连同第 0,1 秒两个时刻派遣的警察(此时第-1 秒时刻派遣的警察已经休息)就可以抵御老鹰第 3 秒时刻的袭击,最后在第 3 秒时刻派遣一名警察,连同第 1,2 秒两个时刻派遣的警察(此时第 0 秒时刻派遣的警察也已经休息)就可以抵御老鹰第 4 秒时刻的袭击,所以至少需要派遣 5 名警察。

Sample2:
样例 2 中,老鹰来袭击 1 次,在第 3 秒时刻,每个警察的巡逻时间为 2 秒,但当老鹰来袭击时至少要有 3 名警察才能抵御老鹰的袭击,按照国王派遣警察的原则,无法实现抵御老鹰的任务,输出“-1”。

这题也挺简单,但在记得从后往前找时要用downto

var
i,j,k,m,n,ans,sum:longint;
b:array[-20000..20000]of longint;
a:array[1..20000]of longint;
begin
    assign(input,'chicken.in');
    assign(output,'chicken.out');
    reset(input);
    rewrite(output);
    read(n,m,k);
    for i:=1 to n do read(a[i]);
    if(k>m)then
    begin
        write(-1);
        close(input);
        close(output);
        exit;
    end;
    for i:=1 to n do
    begin
        sum:=0;
        for j:=a[i]-m to a[i]-1 do
        if(b[j]=1)then inc(sum);
        if(sum<k)then
        begin
            for j:=a[i]-1 downto a[i]-m do
            if(b[j]=0)then
	    begin
                b[j]:=1;
                inc(ans);
                inc(sum);
                if(sum=k)then break;
            end;
        end;
    end;
    write(ans);
    close(input);
    close(output);
end.

T3:

题目描述

鸡国中的母鸡最擅长下蛋了,MGMG 是鸡国中一只以下蛋产量高而闻名全鸡国的母鸡。
鸡国专供下蛋的 n 个鸡窝呈一字排列在鸡国的“下蛋中心”,从左到右依次编号为 1 到n。每个鸡窝都有一个最大可下蛋的量,其中第 i 个鸡窝的最大可下蛋量为 ci。有时候由于MGMG 产量实在太大而无法在一个鸡窝中下完所有的蛋,不得不转移到隔壁的鸡窝继续下蛋,如果隔壁的鸡窝还是不能让它下完所有的蛋,则 MGMG 继续转移,直到下完所有的蛋,或者向“下蛋中心”管理员投诉“鸡窝数量实在太少了,我一只鸡的下蛋量都装不下!”。
为了节省转移时所耗费的体力,请你编程帮助 MGMG 找若干个连续的鸡窝(个数尽量少),让它能下完所有的蛋。

输入

输入共 2 行。
第 1 行输入两个整数 n 和 t,表示“下蛋中心”有 n 个可供下蛋的鸡窝,MGMG 一次总共要下 t 个鸡蛋。
第 2 行 n 个正整数 ci(1≤i≤n),依次表示第 i 个鸡窝最大可下蛋量为 ci个。

输出

输出 1 行一个整数或一个单词。当输出整数时表示让 MGMG 下完所有的蛋至少需要几个连续的鸡窝。当 MGMG 用完所有的鸡窝都无法下完所有的蛋时,MGMG 表示非常愤怒,输出单词“Angry”(不包含双引号,注意大小写)。

样例输入

Input1:
5 4
1 2 1 2 3

Input2:

3 9
3 3 3

Input3:

3 5
1 2 1

样例输出

Output1:
2
Outupt2:
3
Output3:
Angry

数据范围限制

提示

Sample1:
样例 1 中,有 5 个鸡窝,可下蛋量分别为 1,2,1,2,3。MGMG 如果选择第 1,2,3号鸡窝能下完 4 个蛋,但要用 3 个鸡窝,而选择第 4 号和第 5 号鸡窝也能下完 4 个蛋(还有1 个多余的容量),用到的鸡窝只有 2 个。
注意:由于第 2 号和第 4 号鸡窝不连续,不可以作为选择的方案之一。 

Sample2:
样例 2 中,有 3 个鸡窝,可下蛋量分别为 3,3,3,MGMG 可以在这 3 个连续的鸡窝中每个下 3 个蛋,这样正好总共下 9 个蛋。

Sample3:
样例 3 中,所有鸡窝的可下蛋总量小于 MGMG 的下蛋量,无法满足 MGMG 的下蛋需求,输出“Angry”。

这题也简单,用单调队列的思想

#include
#include
using namespace std;
int m,n,k,x,y,a[1001000];
int main(){
	freopen("hen.in","r",stdin);
	freopen("hen.out","w",stdout);
	cin>>n>>m;
	k=2147483647;
	int j=1;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		x=x+a[i];
		y++;
		while(x>=m){
			k=min(y,k);
			x-=a[j];
			y--;
			j++;
		}
	}
	if(k==2147483647)cout<<"Angry";
	else cout<<k;
	return 0;
}

T4:

题目描述

鸡国为了表彰鸡国每一只鸡在过去一年的优秀表现,打算在接下来的 n 天中每天给鸡国的一只鸡发 1 袋或者 2 袋“鸡币”(鸡国的通用货币)作为福利。国王要求每天来领钱鸡互不相同,即来领过钱的鸡不能再来,否则将受到严厉的处罚。
但聪明的鸡国老百姓侦察后发现国王每天发的钱袋子里面装的钱数量是不一样的(同一天的相同),第 i 天发的每一袋钱为 ai元。如果第 i 天来领钱的鸡领 1 袋钱,它可以获得ai元的“鸡币”,如果它领 2 袋钱,则可以获得 2×ai元“鸡币”,当然它也可以放弃,则第i 天的钱国王收回国库。
由于鸡国生活条件优越和鸡的贪念等原因,当第 i 天领钱的鸡同时满足以下两个条件时
它才会感到幸福:
(1)领到的钱不能低于鸡国的平均收入 m 元。
(2)要跟它前面领了钱且感到幸福的鸡一样幸福或者更幸福。
仁慈的国王希望鸡国的每一只鸡都能感到幸福,请你帮国王规划一下在这 n 天中怎样给每一只发钱才能让最多的鸡感到幸福?

输入

输入共 2 行。
第 1 行输入两个整数 n 和 m,分别表示发钱的天数(或理解为来领钱的鸡数)和鸡国的平均收入。
第 2 行 n 个正整数 ai(1≤i≤n),依次表示第 i 天发的一袋钱中的“鸡币”为 ai元。

输出

输出 1 行一个整数,表示最多可以让多少只鸡感到幸福。 

样例输入

Input1:
2 1
2 1
Input2:
3 2
1 2 3
Input3:
6 4
1 2 1 2 1 5

样例输出

Output1:
2
Output2:
3
Output3:
3

数据范围限制

提示

Sample1:
样例 1 中,可以让第 1 天来领钱的第 1 只鸡领 2 元(1 袋),第 2 天来领钱的第 2 只鸡领 2 元(2 袋),最多可以有 2 只鸡感到幸福。

Sample2:
样例 2 中,由于鸡国的平均收入为 2 元,所以领 1 元及以下的鸡是不会感到幸福。可以让第 1 天来领钱的第 1 只鸡领 2 元(2 袋),第 2 天来领钱的第 2 只鸡领 2 元(1 袋),第 3 天来领钱的第 3 只鸡领 3 元(1 袋),最多可以有 3 只鸡感到幸福。

Sample3:
样例 3 中,由于鸡国的平均收入为 4 元,所以第 1 天,第 3 天,第 5 天来领钱的鸡不管领 1 袋钱,或者领 2 袋钱,或者不领都不会感到幸福。可以让第 2 天来领钱的第 2 只鸡领4 元(2 袋),第 4 天来领钱的第 4 只鸡领 4 元(2 袋),第 6 天来领钱的第 6 只鸡领 5 元(1袋),最多可以有 3 只鸡感到幸福。

这题不简单,但对于学过nlogn的最长不下降子序列的人变得简单一些。
但是,我有一个地方不懂,为什么只有i=1的时候a[i]*2还可以在a[i]更改后更改。
请多指教

#include
#include
using namespace std;
int m,n,k,x,y,a[1001000],f[1001000];
int rf(int l,int r,int g){
	int ans=0;
	while(l<=r){
		int mid=(l+r)/2;
		if(f[mid]>g)r=mid-1,ans=mid;
		else l=mid+1;
	}
	return ans;
}
int main(){
	freopen("kingdom.in","r",stdin);
	freopen("kingdom.out","w",stdout); 
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=n;i++){
		if(a[i]>=m){
			if(a[i]>=f[x]){
			   	x++;
				f[x]=a[i];
	    	}
			else{
				int j=rf(1,x,a[i]);
				f[j]=a[i];
			}
		}
		if(a[i]*2>=m){
			if(a[i]*2>=f[x]&&(a[i]<f[x]||i==1)){
			   	x++;
				f[x]=a[i]*2;
	    	}
			else{
				int j=rf(1,x,a[i]*2);
				f[j]=a[i]*2;
			}
		}
	}
	cout<<x;
	return 0;
}

你可能感兴趣的:(比赛,还未搞懂)