2020.02.16【NOIP普及组】模拟赛C组

题目编号标题
0Oliver的成绩(score)
1方格纸(square)
2团队背包(team)
3神奇的项链(fett)

T1

题目描述

Oliver进入初中后,觉得自己不能总是玩儿了,应该要好好学习了。正好一次考试结束了,Oliver想知道自己的语文,数学,英语分别与语文年级第一,数学年级第一,英语年级第一相差多少。由于Oliver所在年级有N个人,所以Oliver想你编个程序帮帮他。

输入

score.in共3N+4行,第一~三行分别为Oliver的语文数学英语成绩(位数M),第四行为N,以下3N行,每行一个数(它们的位数是M),分别为第N个同学的语文,数学,英语成绩。
即:Oliver的语文
 Oliver的数学
 Oliver的英语
 N
第一个人的语文
数学
英语
第二个人的语文
 …

输出

score.out共一行,有三个数,分别为Oliver的语文数学英语与年级第一的差。
如果Oliver是第一,则输出0.

样例输入

10
10
10
3 
0
80
0
40
0
0
0
0 
100

样例输出

30 70 90

数据范围限制

【数据范围】
 对于50%的数据,0<N<1000,0<M<19.
 对于100%的数据,0<N<10000,0<M<30.且都为整数。

西江月·夜行T1中
150多行,提交只有40,重新再来打高精,—次即可AC
做好读入比较,不要忘加特判,超长代码要简化,就能AC此题

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int m,n,k,x,y,a[10010][4][31];
int s[4][31];
int st[4][31];
void read1(int i,int j){
	string s1;
	cin>>s1;
	int k1=s1.size()-1;
	for(int k=30;k>=1;k--){
		a[i][j][k]=s1[k1]-48;
		k1--;
		if(k1<0)break;
	}
}
void read(int i){
	string s1;
	cin>>s1;
	int k=s1.size()-1;
	for(int j=30;j>=1;j--){
		s[i][j]=s1[k]-48;
		k--;
		if(k<0)break;
	}
}
void bj(int i,int j){
	for(int k=1;k<=30;k++){
		if(a[i][j][k]>st[j][k]){
			for(int i1=1;i1<=30;i1++){
				st[j][i1]=a[i][j][i1];
			}
			break;
		}
		else if(st[j][k]>a[i][j][k])break;
	}
}
void gj(int i){
	for(int j=30;j>=1;j--){
		st[i][j]=st[i][j]-s[i][j];
		if(st[i][j]<0){
			st[i][j-1]--;
			st[i][j]+=10;
		}
	}
	for(int j=0;j<=30;j++){
		if(st[i][j]<0){
			cout<<0<<' ';
			return;
		}
	}
	int j=1;
	while(st[i][j]==0)j++;
	while((j<=30)||(j==30&&st[i][j]==0)){
		cout<<st[i][j];
		j++;
	}
	cout<<' ';
}
int main(){
	freopen("score.in","r",stdin);
	freopen("score.out","w",stdout);
	read(1);
	read(2);
	read(3);
	cin>>n;
	memset(st,0,sizeof(st));
	for(int i=1;i<=n;i++){
		read1(i,1);
		read1(i,2);
		read1(i,3);
		bj(i,1);
		bj(i,2);
		bj(i,3);
	}
	gj(1);
	gj(2);
	gj(3);
	return 0;
}

T2

题目描述

今天小D在他的课桌上玩方格纸,现在有一个平面直角坐标系,小D将方块纸放在这个坐标系中,并且方格纸的都与x轴、y轴平行,小D在这上面放了许多的方格纸,然后想知道对于平面直角坐标系中的一个点有多少个方格纸覆盖(包括方格纸的边和点),因为方格纸太多了,所以请聪明的你帮小D解决问题。

输入

第一行 一个正整数N,接下来N行 每行四个正整数x1,y1,x2,y2,分别表示方格纸左下角的坐标和右上角的坐标。
第n+2行一个正整数Q,接下来Q行 每行两个正整数x,y,表示询问点的坐标。

输出

一共Q行,表示对应坐标。

样例输入

3
1 1 5 5
2 2 6 6
3 1 4 3
2
2 2
4 3

样例输出

2
3

数据范围限制

30%的数据, N*Q≤10^7。
100%的数据, N,Q≤10^5,0<x1,y1,x2,y2,x,y≤3000。

0 0 0
0 0 0
0 0 0

-1 0 1
0 0 0
1 0 -1
应该都懂了吧

#include<iostream>
#include<cstdio>
using namespace std;
int m,n,k,x,y,a[3005][3005],b[3005][3005];
int main(){
	freopen("square.in","r",stdin);
	freopen("square.out","w",stdout);
	cin>>n;
	for(int i=1;i<=n;i++){
		int x1,y1,x2,y2;
		cin>>x1>>y1>>x2>>y2;
		a[x1][y1]++;
		a[x2+1][y1]--;
		a[x1][y2+1]--;
		a[x2+1][y2+1]++;
	}
	for(int i=1;i<=3000;i++){
		for(int j=1;j<=3000;j++){
			b[i][j]=a[i][j]+b[i-1][j]+b[i][j-1]-b[i-1][j-1];
		}
	}
	cin>>m;
	for(int i=1;i<=m;i++){
		cin>>x>>y;
		cout<<b[x][y]<<endl;
	}
	return 0;
}

T3

题目描述

DaA 和他的朋友组成一个团队去旅行了。他们每个人都准备了一个背包,用来装旅行用的物品。他们的背包有两个特点:
1. 每个人的背包能装无限多的物品,每种物品有一个价值,但只能装一件;
2. 每个人都很有个性,所以每个人的背包不会完全相同。
DaA 的团队中有M 个人,那么对于整个团队,背包价值和最大是多少呢?

输入

第一行两个整数M、N,表示团队的人数和物品的数量。
接下来一行N 个整数,表示每件物品的价值wi。
数据保证不会出现有空背包人的出现。

输出

一个整数,整个团队背包价值的最大值。

样例输入

Sample Input 1:
2 3
2 7 1
Sample Input 2:
8 4
1 2 3 4

样例输出

Sample Output 1:
19
Sample Output 2:
58

数据范围限制

【数据规模】
30%的数据 1<=M,N<=15。
60%的数据 1<=M<=200,1<=N<=100.
100%的数据 1<=M<=1,000,000,1<=N<=500,0<wi<=50。
输出请注意使用64 位整数(Pascal 中的Int64,C++中的long long)。

这题用01背包
设f[i]表示价值为i的有多少种
f[i]+=f[i-w[j]]
最后再统计

#include<iostream>
#include<cstdio>
using namespace std;
long long m,n,a[1001],f[1001000],ans,maxx;
int main(){
	freopen("team.in","r",stdin);
	freopen("team.out","w",stdout);
	cin>>m>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		maxx=maxx+a[i];
	}
	f[0]=1;
	for(int i=1;i<=n;i++){
		for(int j=maxx;j>=a[i];j--){
			f[j]=f[j]+f[j-a[i]];
		}
	}
	for(int i=maxx;i>=1;i--){
		if(f[i]!=0){
			if(m>=f[i]){
				ans=ans+f[i]*i;
				m=m-f[i];
			}
			else{
				ans=ans+m*i;
				m=0;
			}
		}
		if(m==0)break;
	}
	cout<<ans;
	return 0;
}

T4

题目描述

从前有一条神奇的项链,为什么说它神奇呢?因为它有两个性质:
1. 神奇的项链可以拉成一条线,线上依次是N 个珠子,每个珠子有一个能量值Ei;
2. 除了第一个和最后一个珠子,其他珠子都满足Ei=(Ei-1+Ei+1)/2+Di。
由于这条项链很长,我们只能知道其两端珠子的能量值。并且我们知道每个珠子的Di是多少。请聪明的你求出这N 个珠子的能量值分别是多少。

输入

第一行三个整数N、E1、EN,表示珠子个数N,第一个珠子和第N 个珠子的能量值。
第二行N-2 个整数,表示第2 个珠子到第N-1 个珠子的Di。

输出

输出仅一行,N 个整数,表示1 到N 个这N 个珠子各自的能量值Ei。
请放心,数据保证对于任意珠子满足(Ei-1+Ei+1)Mod 2=0

样例输入

Sample Input 1:
4 1 4
0 0
Sample Input 2:
10 1 22
1 2 -3 5 1 4 2 -1

样例输出

Sample Output 1:
1 2 3 4

Sample Output 2:
1 14 25 32 45 48 49 42 31 22

数据范围限制

40%的数据 1<N<=100。
70%的数据 1<N<=5,000,所有数据(包括计算中的)不超过10^9。
100%的数据 1<N<=500,000,|E1|、|EN|<=10^14,|Di|<=10^4。

二分答案
通过Ei=(Ei-1+Ei+1)/2+Di,我们可以推出Ei+1=(Ei-Di)*2-Ei-1
也就是说知道E2就知道全部
二分E2
如果En和输入进来的一样,就输出

#include<iostream>
#include<cstdio>
using namespace std;
long long m,n,k,x,y,a[500001];
long long d[500001];
int main(){
	freopen("fett.in","r",stdin);
	freopen("fett.out","w",stdout);
	cin>>n>>a[1];
	cin>>k;
	for(int i=2;i<n;i++)cin>>d[i];
	long long l=-2147483647;
	long long r=-l;
	while(l<=r){
		long long mid=(l+r>>1);
		a[2]=mid;
		for(int i=2;i<n;i++){
			a[i+1]=(a[i]-d[i])*2-a[i-1];
		}
		if(a[n]==k){
			for(int i=1;i<=n;i++){
				cout<<a[i]<<' '; 
			}
			return 0;
		}
		if(a[n]>k){
			r=mid;
		}else{
			l=mid;
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值