码迷,mamicode.com
首页 > 其他好文 > 详细

2016.05.14下午【2016纪念中学新初一】基础赛

时间:2016-05-27 11:44:02      阅读:869      评论:0      收藏:0      [点我收藏+]

标签:

前言:

       这次考试,考的不是很理想,满分500,我只得了210,只能说自己太粗心了,很多可以得分的都丢掉了,后悔考试的时候没有很认真。总体来说,这次比赛的题目还算简单,最后一题稍微难一点,不过还是比较容易。
                                     1、第一次OJ大战 

题目描述:

      信息学爱好者们都酷爱在OJ(OJ是Online Judge系统的简称,用来在线检测程序源代码的正确性)上刷题,东莞某中学的OJ因为同学们乱交程序,评测系统因此被卡得无法呼吸,而不堪重负的系统面临崩溃的危险,为了给系统减轻压力,你需要为它判定程序的正误。现在,小X找上了你,请你帮助解决问题。
     给出score(得分),target(满分),time(限时),rtime(运行时间)。由于系统受损,得分可能会大于满分,所以你必须将score除以10,直到score≤target。接着进行以下操作:
    ①若rtime> time,则输出“Time Limit Exceeded”。
    ②若rtime≤time但score<target,则输出“Wrong answer”。
    ③若rtime≤time且score=target,则输出“Accepted”。(不包括引号)


输入:
      第一行一个整数N,表示有N个得分需要纠正,接下来N行数据,分别是score(得分),target(满分),time(限时),rtime(运行时间)。

输出:
      共N行,每行一种状态。

样例输入:

【样例输入1】
2
1000 100 1000 258
9998 100 2000 1875
【样例输入2】
4
10 7 100 8
37 20 8 9
81 8 7 9
74 7 3 1

样例输出:
【样例输出1】
Accepted
Wrong answer
【样例输出2】
Wrong answer
Time Limit Exceeded
Time Limit Exceeded
Wrong answer
 

数据范围限制

20% N<=1000 50% N<=10000 100% 所有输入<=10^7

提示

【样例1解释】 因为1000>100,所以1000÷10=100。因为100=100,且rtime<time,所以输出Accepted。 因为9998>100,所以9998÷100=99.98,因为99.98<100,但rtime<time,所以输出Wrong answer
解题思路:
这道题很简单,就是几个if语句,可是考试的时候,我把大写换成了小写,失了100分,可怜!
代码实现:
<span style="background-color: rgb(255, 255, 255);"><span style="background-color: rgb(255, 255, 255);"><span style="font-size:14px;">var
        n,i,b,c,d:longint;
        a:real;
begin
        assign(input,'oj.in');reset(input);
        assign(output,'oj.out');rewrite(output);
        readln(n);
        for i:=1 to n do
        begin
                readln(a,b,c,d);
                while a>b do
                        a:=a/10;
                if d>c then
                        writeln('Time Limit Exceeded')
                else
                if (d<=c)and(a<b) then
                        writeln('Wrong answer')
                else
                if (d<=c)and(a=b) then
                        writeln('Accepted');
        end;
        close(input);close(output);
end.</span></span>

2、数方格

题目描述:

      余姚市要新建一个广场,为了美观,要求完全是正方形。目前正在规划当中,正方形的大小和位置都在热烈的讨论之中。假设将可用于造广场的区域看成一个矩形,由1*1的单位正方形构成。如下图:这是一个4*6的矩形区域。
技术分享
      广场要求必须在这个矩形范围内,广场边线不能跨过任意一个单位正方形内部,只能与正方形边线重合,且广场必须为正方形。那么上图中,以下4种均为可行方案: 
技术分享
      市民们提出了很多建造广场的方案。现在领导想要知道,到底有多少种不同的方案可以选择?请你设计一个程序,来计算以下建造广场的最多可行方案数。

输入

第一行两个整数n和m,表示用于建造广场区域的长和宽。

输出

一个整数,建造广场的可行方案数。

样例输入

Sample Input1:
1 5
Sample Input2:
4 6
Sample Input3:
6 4

样例输出

Sample Output1:
5
Sample Output2:
50
Sample Output3:
50

数据范围限制

对于40%的数据,n=1
对于70%的数据,1<=n<=m<=100
对于100%的数据,1<=n,m<=1000

提示

【样例1解释】
1*5的矩形,只能构成1*1的正方形。共有5种不同的建造方法。

【样例2解释】
4*6的矩形中,边长为1的正方形有4*6个,边长为2的正方形有3*5个,边长为3的有2*4个,边长为4的的有1*3个。共有24+15+8+3=50个。

【样例3解释】
和样例2一样,只是行列不同。
解题思路:
        这个就是运用了一个乘法原理。看样例解释2,不难发现,24=4*6,15+3*5,8=2*4,3=1*3,于是加起来就是50个,所以,推出规律,就是累加当前n*m的积,然后n,m每次减去1,直到较小的一方等于0的时候结束。

代码实现:

<span style="background-color: rgb(255, 255, 255);"><span style="font-size:14px;">var
        a,b,ans:longint;
begin
        assign(input,'square.in');reset(input);
        assign(output,'square.out');rewrite(output);
        readln(a,b);
        while (a<>0)and(b<>0) do//就是直到较小一方是0就停止
        begin
                ans:=ans+a*b;//累加
                dec(a);
                dec(b);//每次减1
        end;
        writeln(ans);//输出结果
        close(input);close(output);
end.</span></span>

3、高校录取

题目描述

       高三全省联合模拟考试刚刚结束,经过各科老师的努力,各个学科的改卷工作终于结束了,每位同学的各科分数也已经结算完毕。此时,老师们开始模拟各个高校录取情况。
       每个大学有自己的录取范围。例如,清华、北大招生约为理科全省前100名,复旦、上海交大在全省理科101至300名。老师们想要知道哪些同学可以进入某个名校。
       可是,统计软件突然失灵,查询和比对工作也无法进行,只有事先已经得到的理科每位同学的各科成绩。现在请你帮助老师编写一个程序,显示出可以进入某高校的名单。
       此次考试理科排名规则:
       1.按照语文、数学、外语、理科综合四门科目总分由高到低排名
       2.若总分相同,则按照数学成绩由高到低排名;
       3.若总分和数学成绩都相同,按照理科综合成绩由高到低排名;
       4.若总分、数学、理科综合都相同,按照语文成绩由高到低排名;
       5.若总分、数学、理科综合、语文成绩都相同,则按照报名序号小到大排序(这里报名序号为输入顺序,第1个输入就是1号,第100个输入就是100号)。

输入

第一行三个整数n,a和b,分别表示参加考试的人数和某高校的录取名次范围(从名次a到名次b)。
接下来n行,每行4个整数,表示每位同学的每门学科的成绩。依次为语文、数学、英语、综合。成绩0<=x<=300。

输出

输出b-a+1行,排名在a~b名的同学信息。
每行两个整数,分别为报名序号和总分(报名序号看题目描述),中间用空格分开。

样例输入

Sample Input1:
6 3 5
118 139 130 286
105 130 129 296
113 138 123 291
104 133 119 283
89 139 116 287
103 127 118 288
Sample Input2:
7 3 5
118 139 130 286
105 130 129 296
113 138 123 291
105 130 129 296
89 139 116 287
107 127 116 286
103 127 118 288

样例输出

Sample Output1:
2 660
4 639
6 636
Sample Output2:
2 660
4 660
7 636

数据范围限制

对于40%的数据,1<=a<=b<=n<=100,且保证每个人的总分都不相同。
对于70%的数据,1<=a<=b<=n<=300。
对于100%的数据,1<=a<=b<=n<=100000。
 

提示

【样例1解释】
排序后由高到低
序号                总分
1 118 139 130 286 673
3 113 138 123 291 665
2 105 130 129 296 660
4 104 133 119 283 639
6 103 127 118 288 636
5 89 139 116 287 631
输出3~5名的序号和总分


【样例2解释】
排序后由高到低
序号                总分
1 118 139 130 286 673
3 113 138 123 291 665
2 105 130 129 296 660
4 105 130 129 296 660
7 103 127 118 288 636
6 107 127 116 286 636
5 89 139 116 287 631
7号和6号同为636分,数学分数又相同,理科综合分数7号较高,因此排在6号前面。
2号和4号所有成绩都相同,只能按照序号排序,2号在4号之前
解题思路:
     这个就相当于一个快排的改进,只需要在while的地方改一下,如果第一个条件相等,比较第二个,如果第二个也相等,比较第三个……考试的时候打while懒得打,直接复制,然后忘记改了,而且有些x就变成了y,导致只得了10分。
代码实现:
<span style="background-color: rgb(255, 255, 255);"><span style="font-size:14px;">var
        a,b,c,d,num,h:array[0..100000] of longint;
        n,i,x,y:longint;
procedure q(l,r:longint);
var
        i,j,t,m,m1,m2,m3,m4:longint;
begin
        i:=l;
        j:=r;
        m:=num[(l+r) div 2];
        m1:=b[(l+r) div 2];
        m2:=d[(l+r) div 2];
        m3:=a[(l+r) div 2];
        m4:=h[(l+r) div 2];//取每个条件的重点
        while i<j do
        begin
                while (num[i]>m)or((num[i]=m)and(b[i]>m1))or((num[i]=m)and(b[i]=m1)and(d[i]>m2))or((num[i]=m)and(b[i]=m1)and(d[i]=m2)and(a[i]>m3))or((num[i]=m)and(b[i]=m1)and(d[i]=m2)and(a[i]=m3)and(h[i]<m4))do inc(i);
                while (num[j]<m)or((num[j]=m)and(b[j]<m1))or((num[j]=m)and(b[j]=m1)and(d[j]<m2))or((num[j]=m)and(b[j]=m1)and(d[j]=m2)and(a[j]<m3))or((num[j]=m)and(b[j]=m1)and(d[j]=m2)and(a[j]=m3)and(h[j]>m4))do dec(j);//一个个比较,注意大于小于符号,这个就是按照条件的优先来排的。
                if i<=j then
                begin
                        t:=num[i];
                        num[i]:=num[j];
                        num[j]:=t;
                        t:=h[i];
                        h[i]:=h[j];
                        h[j]:=t;
                        t:=a[i];
                        a[i]:=a[j];
                        a[j]:=t;
                        t:=b[i];
                        b[i]:=b[j];
                        b[j]:=t;
                        t:=c[i];
                        c[i]:=c[j];
                        c[j]:=t;
                        t:=d[i];
                        d[i]:=d[j];
                        d[j]:=t;//交换要全部交换完,不要漏掉
                        inc(i);
                        dec(j);
                end;
        end;
        if l<j then q(l,j);
        if i<r then q(i,r);//跟原先快拍一样
end;
begin
        assign(input,'range.in');reset(input);
        assign(output,'range.out');rewrite(output);
        readln(n,x,y);
        for i:=1 to n do
        begin
                readln(a[i],b[i],c[i],d[i]);
                num[i]:=a[i]+b[i]+c[i]+d[i];//总分
                h[i]:=i;//序号
        end;
        q(1,n);
        for i:=x to y do
                writeln(h[i],' ',num[i]);
        close(input);close(output);
end.</span></span>
 

4、围墙翻新

题目描述

小明的破旧围栏又要喷涂油漆了。围栏由N个木板构成,每个宽度都为1cm,但是高度各不相同。他给自己买了一个喷漆机器,喷涂头恰好也是1cm宽。
小明的喷漆机器是直接喷射的,因此喷头的每一个部位必须一直接触到木板,否则尤其会污染他的农田。并且机器也必须时刻与地面平行。可以看出,小明每次必须在同一高度对木板喷涂,可以从左到右直到没有围栏可以喷漆。这样,若干次喷漆之后,就可以将围栏翻新啦!
由于机器的特殊性,小明希望喷涂的次数尽量的少。如下图的围栏情况,共有5块木板,高度分别为2,3,4,1,2。第一次可以刷1~5,第二次刷1~3,第三次刷2~3,第四次刷3~3,第五次刷5~5。5次就可以刷完!(刷的顺序可以随意调整,也可以从上面开始刷)
技术分享
小明想要知道至少需要刷多少次就可以把围栏都刷完,请你帮忙计算一下!

输入

第一行一个整数N,表示木板数量。
接下来一行N个整数,表示每块木板依次的高度。

输出

翻新围栏所需的最少喷漆次数。

样例输入

5
2 3 4 1 2

样例输出

5

数据范围限制

30%的数据1<=n<=10
70%的数据1<=n<=1000
100%的数据1<=n<=100000,对于每个木板的高度0<=hi<=10000。
解题思路:
   在考试前做过原题,记得有个公式,可是忘记了,于是死做,还好得了80分,不算丢脸。正解就是如果当前的围墙高度比上一个围墙的高,那么油漆的次数就是当前围墙高度减去上一个围墙的高度。
代码实现:
<span style="background-color: rgb(255, 255, 255);"><span style="font-size:14px;">var
         i,n,x,y,s:longint; 
begin
         assign(input,'paint.in');reset(input);
         assign(output,'paint.out');rewrite(output);
         readln(n); 
         for i:=1 to n do
         begin
                read(x); 
                if x>y then s:=s+x-y; //<span style="color: rgb(51, 51, 51); font-family: KaiTi_GB2312;font-size:18px;">油漆的次数就是当前围墙高度减去上一个围墙的高度</span>
                y:=x; //记录上一个
         end; 
         write(s); 
         close(input);close(output);
end. </span></span>

5、车站检票

题目描述

       Y学校共派出M名选手参加NOIP2013,现在他们正赶往火车站参加比赛。火车站共有N个检票口。由于检票员的操作速度不同,每个检票口的通行速度也就不同,平均测量,第k个检票口的速度为Tk秒。
       在候车时,精于计算的选手们就开始思考,假设一开始所有检票口都处于准备状态,每个检票口一次只能通过一人。那么M名选手至少需要多少时间全部通过检票口。

输入

第一行两个整数,N(1<=N<=100000)和M(1<=M<=10^9)。分别表示检票口数量以及人数。
接下来N行,每行一个整数,表示每个检票口的检票时间。范围在[1,10^9]。

输出

仅一行,输出全部通过的最少时间。

样例输入

Sample Input1:
2 6
7
10


Sample Input2:
7 10
3
8
3
6
9
2
4

样例输出

Sample Output1:
28

Sample Output2:
8

数据范围限制

对于40%的数据,M<=20.
对于70%的数据,M<=1000.
对于100%的数据,M<=10^9.

提示

【样例1解释】
时间28,第一出口4人,第二出口2人。27无法通过。

【样例2解释】
时间8可以全部通过,第一个出口2人,第二个1人,第三个2人,第四个1人,第六个4人。而时间7是无法通过10人的。
解题思路:
    这道题,刚看到数据就懵逼了,太大的数据了!我考试的时候,用了递归加了一点点优化,结果TLE30分,后来经人点拨,原来这道题是用二分,二分一共需要的时间,假设最小时间为0,最大时间为数列中max*人数,然后一个个枚举,看看人数能不能达到共有人数,如果有多的也可以,因为有的窗口可以少1个人排队。
代码实现:
<span style="font-size:14px;">var
        i:longint;
        min,l,r,mid,n,m,ans,max:int64;//一定要用int64,数据太大,无法直视
        a:array[0..100000] of longint;
begin
        assign(input,'check.in');reset(input);
        assign(output,'check.out');rewrite(output);

        readln(n,m);
        for i:=1 to n do
        begin
                readln(a[i]);
                if a[i]>max then max:=a[i];
        end;
        r:=max*m;//这个是最大的时间,l=0,我省略了
        min:=9000000000000;//题目最大数据的结果就是这个,比maxlongint还大,所以这个要注意一下。
        while l<=r do
        begin
                mid:=(l+r) div 2;
                ans:=0;//累加最多能存的人
                for i:=1 to n do
                        ans:=ans+mid div a[i];
                if ans>=m then//如果大于m人数或者等于,就判断,然后记录下来,同时r要跟ans>m的情况一样。
                begin
                        if mid<min then min:=mid;
                        r:=mid-1;
                end;
                if ans>m then
                        r:=mid-1
                else
                if ans<m then
                        l:=mid+1;//典型二分,多了个累加而已
        end;
        writeln(min);//输出

        close(input);close(output);
end.</span>

2016.05.14下午【2016纪念中学新初一】基础赛

标签:

原文地址:http://blog.csdn.net/fengyingjie2/article/details/51509627

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!