2019.6.20义乌市正式赛

话不多说

A题原题传送门.

题目描述

龙猫T在魔法学校已经度过了愉快的一个学期,在这个学期里一共经历了N次魔法测试,每次测试都会有一个分数。
现在给你龙猫T的N次的魔法成绩,请帮他计算有效成绩的平均分。

输入格式

第1行:一个正整数N。
第2…N+1行,每行一个正整数,表示一次成绩。

输出格式

龙猫T的平均分。(保留2位小数)

输入样例

5
36
25
47
14
55

输出样例

35.40

数据范围

对于100%的数据:1<=N<=1000,所有的成绩不超过10000

分析

水题一道,不用分析了,直接上代码

代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e3+10;
int n,x,sum;
int read(){
   	int x=0,f=1;
   	char c=getchar();
   	while(c<'0'||c>'9'){
   			if(c=='-') f=-1;
   			c=getchar();
   	}
   	while(c>='0'&&c<='9'){
   			x=x*10+c-'0';
   			c=getchar();
   	}
   	return x*f;
}
int main(){
   	n=read();
   	for(int i=1;i<=n;i++){
   			x=read();
   			sum+=x;
   	}
   	printf("%.2lf",(double)sum/n);
   	return 0;
}

B题原题传送门.

题目描述

经过一个多月的魔法学习,龙猫T发现要想学好魔法,必须先学好数学。
龙猫T在今天的数学课上又一次感受到了数学的重要性。魔法老师介绍了魔法变化中很重要的一种数:非降数。
非降数是指数字中的每一位(除了最高位)都比它相邻的前一位大或者相等,如:1123就是非降数。
现在给你一个N位数,请你帮助龙猫T判断它是否为非降数。

输入格式

一个正整数,位数不超过100位。

输出格式

如果是非降数,输出“Yes”,否则输出“No”

输入样例1

1123

输出样例1

Yes

输入样例2

1056

输出样例2

No

数据范围

分析

用getchar()掉进Windows和Linux系统的坑——换行符\n->\r\n
应该用string,使程序兼容性更强,更强壮

代码

#include<bits/stdc++.h>
using namespace std;
string s; 
int main(){
   	cin>>s;
   	for(int i=1;i<s.size();i++)
   	    if(s[i]<s[i-1]){
   	    	printf("No\n");
   	    	return 0;
   		}
   	printf("Yes\n");
   	return 0;
}

C题原题传送门.

题目描述

今天,龙猫T跟鼠牛A学习了一个新魔法,据说是鼠牛A自己研究出来的。好厉害啊!这个魔法的神奇功能是可以把连续K个物体的高度变小,哇!这可是个非常有用的魔法。龙猫T迫不及待地勤加练习。
但是不久,龙猫T发现了一个问题,这个魔法有时有效,有时无效。经过长时间的试验,龙猫T终于发现了问题所在,原来,这个魔法只能对连续K个物体的最大平均高度起作用。
现在给你N个物体的高度,请你帮龙猫T计算连续K个物体的最大平均高度。只要求输出最大平均高度的1000倍,不要求舍入求整。

输入格式

第1行:两个正整数N、K,分别表示总的物体个数和要求计算的连续物体个数。
第2…N+1行,每行一个正整数,表示一个物体的高度。

输出格式

一个整数,它是最大平均高度的1000倍,不要求舍入求整。

输入样例

10 6
6
4
2
10
3
8
5
9
4
1

输出样例

6500

数据范围

对于100%的数据:1<=N<=100000,K<=N,物体的高度不超过2000。

分析

最简单的是模拟,显然是O(n*k)的复杂度
我们发现[i,i+k-1]与[i+1,i+k]的和只相差|a[i]-a[i+k]|,所以每读入一个数,只要进行一次运算,复杂度为O(n)

代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e5+10;
long long n,k,maxn,sum;
long long a[MAXN];
long long read(){
   	long long x=0,f=1;
   	char c=getchar();
   	while(c<'0'||c>'9'){
   			if(c=='-') f=-1;
   			c=getchar();
   	}
   	while(c>='0'&&c<='9'){
   			x=x*10+c-'0';
   			c=getchar();
   	}
   	return x*f;
}
int main(){
   	cin>>n>>k;
   	for(int i=1;i<=n;i++) a[i]=read();
   	for(int i=1;i<=k;i++) sum+=a[i];
   	maxn=sum;
   	for(int i=k+1;i<=n;i++){
   		sum=sum-a[i-k]+a[i];
   		maxn=max(sum,maxn);
   	}
   	printf("%d\n",maxn*1000/k);
   	return 0;
}

D题原题传送门.

题目描述

魔法综合能力排位赛开始了,龙猫T终于可以和鼠牛A一决高下。
排位的方式很简单,就是比总分成绩,谁在全校的排名高,谁就赢。排名的方式很奇特,按照各个位置上数字之和从大到小排序。如果和相同,则大数排前面。
现在给你魔法学校N位学员的成绩,请你帮忙按以上规则进行排名。

输入格式

第1行:一个正整数N。
第2…N+1行,每行一个正整数,表示一位同学的成绩。

输出格式

N行,每行一个数。

输入样例

5
111
152
116
267
354

输出样例

267
354
152
116
111

数据范围

对于100%的数据:1<=N<=30000(已更改), 成绩不超过100000

分析

结构体排序,以各位数之和为第一关键字,以数的大小为第二关键字

代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e4+10;
struct Node{
int num,sum;
}a[MAXN];
int n;
bool cmp(Node x,Node y){
   	if(x.sum==y.sum) return x.num>y.num;
   	return x.sum>y.sum;
}
int main(){
   	cin>>n;
   	for(int i=1;i<=n;i++){
   			cin>>a[i].num;
   			int b=a[i].num,c=0;
   			while(b){
   				c+=b%10;
   				b/=10;
   			}
   			a[i].sum=c;
   	}
   	sort(a+1,a+n+1,cmp);
   	for(int i=1;i<=n;i++) printf("%d\n",a[i].num);
   	return 0;
}

E题原题传送门.

题目描述

龙猫T实在无法忍受魔法学校里的宿舍了,由于水龙头太少,每天早上洗漱时的等待时间让他抓狂。
好消息终于来了,学校决定重建校舍。但是到底要设多少个水龙头才合适呢,校长把这个艰巨而又伟大的任务交给了龙猫T。
龙猫T经过一段时间的观察,发现每个学员每天起床后在水龙头前排队的先后顺序是固定的,所以洗漱顺序是固定的,更令他惊讶的是,每个学员的洗漱时间也是固定的(嗯~,好像自己也是这样的)。如果有K个水龙头,前K个学员进行洗漱,当其中一个学员洗漱完毕,第K+1个学员进行洗漱,再有一个学员洗漱完毕,第K+2个学员进行洗漱,以此类推。从第1个学员开始到最后一个学员洗漱完毕所用的总时间为X。
但是课前洗漱时间是有限的,龙猫T经过观察,计算出了用于洗漱的最多时间X,请你帮助他计算一下,在最多有X时间的前提下能够让所有学员完成洗漱,最少需要安装多少个水龙头呢?

输入格式

第1行:两个用空格隔开的正整数N、X,分别表示学员数、上课前用于洗漱的最多时间。(每个学员的洗漱时间不会超过X) 第2…N+1行:每行一个学员的洗漱所用时间。

输出格式

一个整数,即最少需要安装的水龙头数量。

输入样例1

5 8
4
7
8
6
4

输出样例1

4

输入样例2

6 16
5
9
8
4
6
7

输出样例2

3

数据范围

对于100%的数据:1<=N<=10000,X<=10^9,每个学员的洗漱时间不超过100000。

分析

暴力出奇迹,可以用优先队列优化所查找的最先洗漱完的水龙头

代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e4+10;
const int INF=0x3f3f3f3f;
int n,t,ans,l,r,mid;
int a[MAXN];
int read(){
   	int x=0,f=1;
   	char c=getchar();
   	while(c<'0'||c>'9'){
   		if(c=='-') f=-1;
   		c=getchar();
   	}
   	while(c>='0'&&c<='9'){
   		x=x*10+c-'0';
   		c=getchar();
   	}
   	return x*f;
}
bool check(int x){
   	priority_queue<int,vector<int>,greater<int> > b;
   	for(int i=1;i<=x;i++) b.push(a[i]);
   	for(int i=x+1;i<=n;i++){
   		int tmp=b.top();
   		b.pop();
   		tmp+=a[i];
   		if(tmp>t) return 0;
   		b.push(tmp);
   	}
   	return 1;
}
int main(){
   	n=read(),t=read();
   	for(int i=1;i<=n;i++) a[i]=read();
   	l=1,r=n;
   	while(l<=r){
   		mid=(l+r)>>1;
   		if(check(mid)){
   			ans=mid;
   			r=mid-1;
   		}
   		else l=mid+1;
   	}
   	printf("%d\n",ans);
   	return 0;
}

F题原题传送门.

题目描述

一年一度的“最强魔法师”争霸赛开始了,每个魔法学校都要派最顶尖的魔法师团队前去参加。
今年学校要派两只队伍参赛,分别是咒语派和药水派,龙猫T所在的咒语派壮志雄心,自信满满,去年输给了药水派,今年志在必得。而药水派也不甘示弱,早就扬言今年必定蝉联。学校里两队的拉拉队也针锋相对,谁也不服谁。
现在学校里的N位学员组成的拉拉队要去赛场助威,每位学员已经排成一列队伍,按照排好队伍的先后顺序依次上车。但如果一辆车里其中一个拉拉队的人数过多,就会发生冲突,因此,必须保证一辆车里两个拉拉队的人数差不能超过K(1<=K<=N),或者是整车的人都是同一个拉拉队的。
已知学员的上车顺序,即:每一个时刻只可以有一名学员上车,如果该学员没有上这辆车,并且这辆车里面已经有学员了,那么这辆车不会再载该学员之后的学员(即该学员以及该学员之后的学员再也不能上这辆车了,这辆车可以开走了)。
校长为学校提供了强大的魔法车,车内人数没有限制!当然车辆也是无限多的!然而提供一辆魔法车,需要消耗一定的魔法能量,所以校长希望使用的车辆越少越好。要怎样安排才能保证使用的车辆最少呢?
校长把这个艰巨的任务交给了龙猫T,请你帮助龙猫T安排最少需要几辆车。

输入格式

第1行:两个正整数N、K,分别表示拉拉队总人数和两派最多人数差。
第2…N+1行,每行一个字母H(代表咒语派拉拉队)或J(代表药水派拉拉队),表示各派学员的上车顺序。

输出格式

一个整数,最少使用的车辆数。

输入样例

14 3
H
J
H
H
H
J
H
J
H
H
H
H
H
H

数据范围

对于100%的数据:1<=N<=2500

分析

典型的动态规划,设f[i]表示前i位童鞋不干架所需的最少车辆数,j表示i之前的一位同学,若j~i在同一辆车上,则f[i]=min{ f[i],f[j-1]+1 | 1<=j<=i};

代码

#include<bits/stdc++.h>
using namespace std;
const int MAXN=3e3+10;
int n,k;
int f[MAXN],sum1[MAXN],sum2[MAXN];
char c[MAXN];
int main(){
   	cin>>n>>k;
   	for(int i=1;i<=n;i++){
   		cin>>c[i];
   		if(c[i]=='H') sum1[i]=sum1[i-1]+1,sum2[i]=sum2[i-1];
   		else sum2[i]=sum2[i-1]+1,sum1[i]=sum1[i-1];
   	}
   	for(int i=1;i<=n;i++) f[i]=2147483647;
   	for(int i=1;i<=n;i++)
   		for(int j=1;j<=i;j++)
   			if(abs(sum1[i]-sum1[j-1]-sum2[i]+sum2[j-1])<=k||sum1[i]-sum1[j-1]==i-j+1||sum2[i]-sum2[j-1]==i-j+1) f[i]=min(f[j-1]+1,f[i]);
   			else f[i]=min(f[i-1]+1,f[i]);
   	printf("%d\n",f[n]);
   	return 0;
}

总结:小错误多多,以至于只有410,希望下次注意

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值