2017年12月30日迎新挑战赛题解

2017年12月30日迎新挑战赛题解

     这次考试无疑是我最悲伤的一次考试了。为什么就先不说了,先将题解写完再说(虽然我还有两题没有AC,但是我A掉之后我还是会补上来的)。

一、    IQ

题目简述:现在有信息学和数学两个竞赛班。如果我们把学信息学的一些学生调去学数学,那么两个竞赛的学生平均IQ都会提升。现在给出一群数学竞赛全体学生的IQ和信息学竞赛全体学生的IQ,问最多能把几个学信息学的学生调去学数学,而两个竞赛的学生平均IQ都有提升呢?

每次只调一个学生,而且每次调配,两个竞赛的学生平均IQ都要提升。

       分析:这道题其实很容易看出来是要求平均值。首先要一个判断(信息学的平均IQ大于原有IQ,且数学的平均IQ小于平均IQ),因为只有这种情况,才能进行调整。(因为数学组的平均IQ仍没上升,但是信息学的IQ却还满足条件)。

   那我们在这里就要思考一下:要排序吗?如果要,要对谁进行排序?怎么排序?这都是我们要思考的问题。

   很显然,排序是肯定要的。那么对谁排序呢?好吧,要对信息学的学生的IQ进行排序,是从小到大排序。因为只有将信息学IQ小的学生调过去,信息学组的IQ才有可能提升,数学也是如此。

   那么具体代码如下:

#include<bits/stdc++.h>

using namespace std;

int main(){

   doublesx1,sx2;//注意是平均值,所以要实型

   intn,m,a[10001],b[10001],n2,ans=0;

   scanf("%d",&n);

   for (inti=1;i<=n;i++) scanf("%d",&a[i]),sx1+=a[i];//先累加,对后面求平均值有用

   scanf("%d",&m);

   for (int i=1;i<=m;i++)scanf("%d",&b[i]),sx2+=b[i];//同样

   n2=m;//先将信息学小组的学生个数记录下来

   sort(b+1,b+m+1);//排序

   for (inti=1;i<=n2;i++)//要循环信息学组的IQ,并要进行比较

     if (sx2/m>b[i]&&sx1/n<b[i]){//判断条件

     n++;//因为掉到了数学小组中,所以数学小组人数要加一

     m--;//同样,信息学小组的人数减一

     sx2-=b[i];//信息学的总IQ减去当前学生的IQ

     sx1+=b[i];数学的加上

     ans++;//一个学生累加

     }

     cout<<ans;//输出

     return 0;

}

 

总结:这道题我当时只拿了很少的一点部分分,就是因为一些条件判断有问题,现在也是终于理解的,真是粗心难改啊!

二、    工厂

题目简述; 有n个部件需要在A、B机器上加工,每个工件都必须经过先A后B两道工序。已知:部件i在A、B机器上的加工时间粉笔为ai,bi。问:如何安排n个工件的加工顺序,才能使得总加工时间最短?

这道题我目前还没AC,但是我知道是工序问题。所以等我看完工序问题之后再来补上吧。

三、    YJH家的树

题目简述:YJH家有万亩树林,他的好朋友CZ需要一些木头,于是YJH指定了N棵树,每棵都有一个整数高度。CZ需要的木头的总需要量为M。 现在需要确定一个最大的统一的砍树高度H,如果某棵树的高度大于H,则高出的部分被砍下。使得所有被砍下的木材长度之和达到M(允许稍超过M)。

例如,有4棵树,高度分别是20 15 10 17, 需要的木材长度为 7,砍树高度为15时,第1棵树被砍下5,第4棵树被砍下2,得到的总长度为7。如果砍树高度为16时,第1棵树被砍下4,第4棵树被砍下1,则得到的木材数量为5。给定N和M,请你编程帮YJH和CZ求出砍树的高度 H。

 

分析:这道题我第一眼看到后的感觉就是二分,但是由于二分写炸了。。结束之后我有学到了一个桶排思想。现将有的木头的所对应的高度的桶累加。在一个循环判断,这里说这个循环还有点麻烦,具体怎样在带马上看吧。

那么具体代码如下:

#include<bits/stdc++.h>

using namespace std;

int main(){

int n,a[10000001]={},maxx=0,x=0,s=0,ans=0,k=0,ss=0;

scanf("%d%d",&n,&k);

for (int i=1;i<=n;i++){

      scanf("%d",&x);

      maxx=max(maxx,x);//首先记录最大值,这样后面循环的初值就有了目标。

      a[x]++;//累加

}

for (ans=maxx;ss<k;ans--){//ans为数目的高度,首先从最大高度开始循环,如果总高度ss没到达期望高度,那么就继续累加

    s+=a[ans];//小的累加器先累加上当前树木

    ss+=s;//再加上

}

cout<<ans;//即为数目高度

return 0;

}

 

四、  ZYB的旅游线路

问题简述:旅游景点在江的两边,江北边有N个景点,南边有M个景点,每个景点都有不同的旅游价值,各个景点的连接必须通过江道,也就是说同一个水岸的两个景点不会有旅游线路,只有江两边的景点才会有旅游线路。

   因为会有很多拨游客在这条线路上游玩,为了保证江道划船安全,ZYB必须保证设计的旅游线路不会出现交叉,而出现交叉的定义为:假设a和b在江北岸,x和y在江南岸,假设(a<-> x)是一条线路, (b <-> y)也是一条线路, 如果存在 (a < b and y < x) or (b < a and x < y) or (a = b andx = y),我们认为这两条线路是交叉的。

       现在ZYB的任务设计一条线路,让这条线路的旅游价值累加和最高。当然这条线路可以从任意一个景点开始,任意一个景点结束。

  这道题我第一眼看到以为是图。。但后面才知道原来是一道dp。。当然dp我还没学过。所以这道题我也没有AC,等我学了之后A了之后再补上。

猜你喜欢

转载自blog.csdn.net/huang_ke_hai/article/details/78958033