2008年东莞市特长生测试题

一、聪明的小李
提交文件:num.pas / num.exe
问题描述:
小李的识记能力非常强,一列数他一看就知道最大的是哪个数,这个数在原数列中的位置。现在的问题是给定一个各不相同的正整数数列,要你找出第K大的数是多少,并指出该数在原数列中的位置。
数据输入:
从文件num.in中读入数据,文件共有三行,第一行是一个正整数N,表示原数列共有N个数,第二行是N个正整数,表示原数列中的每一个数。第三行是一个正整数,表示K的值。
数据输出:
结果输出到num.out中,共二行,第一行是一个整数,表示原数列中第K大的数,第二行是一个正整数,表示第K大数在原数列中的位置。
输入输出样例:
num.in
5
34 12 55 42 90
3
num.out
42
4
数据说明:N<=100,数列中所涉及到的数均在整型范围内。

一道水题
先预处理出每个数在原数列的排名
再排序
最后write

**

注意:是从大到小排

**

var
 a,m:array[0..101] of longint;
 i,j,n,s,t:longint;
procedure sort(n:longint);
var
 i,j,t:longint;
begin
 for i:=1 to n do
  for j:=i+1 to n do
    begin
      if a[i]<a[j] then
        begin
          t:=a[i]; a[i]:=a[j]; a[j]:=t;
          t:=m[i]; m[i]:=m[j]; m[j]:=t;
        end;
    end;
end;

begin

read(n);
 for i:=1 to n do
   begin
     read(a[i]);
     m[i]:=i;
   end;
 read(s);
 sort(n);
 writeln(a[s]);
 write(m[s]);
end.

二、吝啬的地主
提交文件:land.pas / land.exe
问题描述:
很久以前,有一户地主对家里的工人“安理”非常的吝啬,工钱也很低,新的一年开始了,地主对安理说“我今年有一块正方形的田地,将它分成了N*N小块,你要好好耕哦,这块地的工钱我另算,你要多少工钱,说说看,让我考虑一下?”安理思考了一下,说“这样吧,在第一小块算1粒米,第二小块算2粒米,第三小块算22=4粒米,第四小块算23=8粒米,以此类推,最后一小块算2n*n-1粒米,每一小块的米的数量和就算是我的工钱了。”地主没什么文化,一口就答应了。现在已知N的值,请你帮安理算一算,这块N*N的田地,他总共能得到多少粒米。
数据输入:
从文件land.in中读入数据,文件中只有一个数,表示N的值。
数据输出:
输出到文件land.out中,只有一个数,表示安理总共能得到的米的粒数。
输入输出样例:
land.in
2
land.out
15
数据说明:
1、20%的结果在整数范围内,40%的结果在长整范围内;
2、70%的结果位数小于250位,100%的结果位数小于500位。

高精度乘法和高精度加法

var
 all:array[0..501]of longint;
 mon:array[0..5001,0..501]of longint;
 i,j,n,s,t,gw,sw,swl:longint;
begin

 read(n);
 n:=n*n;
 mon[1,501]:=1;
 mon[2,501]:=2;
 for i:=3 to n do
   begin
     for j:=501 downto 1 do
       begin
         swl:=sw;
         gw:=mon[i-1,j]*2;
         sw:=gw div 10;
         gw:=gw mod 10;
         gw:=gw+swl;
         mon[i,j]:=gw;
       end;
   end;
 for i:=1 to n do
  for j:=501 downto 1 do
    begin
      swl:=sw;
      gw:=all[j]+mon[i,j];
      sw:=gw div 10;
      gw:=gw mod 10;
      gw:=gw+swl;
      all[j]:=gw;
    end;
 //for i:=1 to 3 do
 // write(all[i]);
 i:=1;
 while all[i]=0 do inc(i);
 for j:=i to 501 do
 write(all[j]);

end.

三、奖金
提交文件:Reward.pas/reward.exe
【题目描述】
由于无敌的凡凡在2005年世界英俊帅气男总决选中胜出,Yali Company总经理Mr.Z心情好,决定给每位员工发奖金。公司决定以每个人本年在公司的贡献为标准来计算他们得到奖金的多少。
于是Mr.Z下令召开m方会谈。每位参加会谈的代表提出了自己的意见:“我认为员工a的奖金应该比b高!”Mr.Z决定要找出一种奖金方案,满足各位代表的意见,且同时使得总奖金数最少。每位员工奖金最少为100元。

【输入】
第一行两个整数n,m,表示员工总数和代表数;
以下m行,每行2个整数a,b,表示某个代表认为第a号员工奖金应该比第b号员工高。

【输出】
若无法找到合法方案,则输出“-1”;否则输出一个数表示最少总奖金。

输入输出样例
reward.in
2 1
1 2
reward.out
201

【数据范围】
80%的数据满足n<=1000,m<=2000;
100%的数据满足n<=10000,m<=20000。

思路:
将a和b记录成一个有向图,枚举每一个点跑dfs,判断如果在当前路径有点重复就halt

next[i,j]放第i个员工有哪几个员工比他的奖金多
check[i]记录在当前路径时当前点有没有重复
sum[i]记录第i个员工的奖金
money是上一个员工的奖金多少钱

var
 sum:array[0..10001]of longint;
 check:array[0..10001]of boolean;
 next:array[0..10001,0..5001] of longint;
 i,j,n,s,t,a,b,c,ans:longint;
procedure count(i,money:longint);
var
 j:longint;
begin
 if sum[i]<=money then sum[i]:=money+1
 else exit;
 check[i]:=true;//标记
 for j:=1 to next[i,0] do
   begin
     if not(check[next[i,j]]) then count(next[i,j],sum[i])
      else
        begin
          writeln('-1');
          close(input); 
          close(output);
          halt;
        end;//判断是否重复
   end;
 check[i]:=false;//回朔
end;

begin

 read(s,n);
 for i:=1 to n do
   begin
     read(a,b);
     inc(next[b,0]);//记录有几个员工比第i个员工奖金多
     next[b,next[b,0]]:=a;//哪几个员工比第i多奖金多
   end;
 for i:=1 to s do
    begin
      count(i,99);
    end;
 for i:=1 to s do
  ans:=sum[i]+ans;
 write(ans);

end.

四、工作
提交文件:Work.pas/work.exe
题目描述
这次故事的主角是HG!转眼4年过去了,HG本科毕业了,于是找了份工作。每天HG会收到一份任务清单,清单上列出了n个可能需要他完成的任务。每个任务包含3个信息:Ti、Ai、Bi,Ti表示完成此任务需要的时间,Ai表示此任务的到达时间,Bi表示此任务的最晚完成时间。在某一时刻若HG手上没有任务,那么他可以选择一个已经到达且还能够在Bi时刻之前(或者恰好在Bi时刻)完成的任务来做。
由于HG有点懒(纯属虚构:D),他想尽量少的减少他的总工作时间,但是他不能在可以做任务的时候故意不做(这样会被炒鱿鱼的>_<),那么他该如何挑选任务来做呢?
你的任务就是求出HG的最少工作时间(即总共有多少时间HG在做任务)。
数据输入:
从文件work.in读入数据,第一行一个整数n表示任务数。
以下n行,每行三个整数Ti,Ai,Bi。(n<=1000,0<=Ai,Bi<=1500,Ti>=1)
数据输出:
结果输出到work.out,输出仅一个数,即最少工作时间。
输入输出样例:
work.in
3
15 0 25
50 0 90
45 15 70
work.out
50

数据说明:
Ti>=1,0<=Ai,Bi<=1200;
30%的数据满足n<=5;60%的数据满足n<=500;100%的数据满足n<=1000。
输入数据保证Bi-Ai要大于等于Ti,且小于2Ti。

dp题目

f[i]放当前时间点的最少工作时间
顺着跑的动态转移方程
f[i+t[j]]=min(f[i+t[j]],f[i]+t[j])
并且f[i+t[j]]空闲无工作
/思路启发来自zzy大佬,他的博客https://my.csdn.net/sslgzzzy/

倒着跑的思路和方程参考百度贴吧:http://tieba.baidu.com/p/281904526

var
 t,a,b,f:array[0..3001]of longint;
 i,n,s,j,time,start:longint;
 check:boolean;
procedure qsort(l,r:longint);
var
 i,j,mid,c:longint;
begin
 i:=l; j:=r;
 mid:=a[(l+r) div 2];
 repeat
   while a[i]<mid do inc(i);
   while a[j]>mid do dec(j);
   if i<=j then
     begin
       c:=a[i]; a[i]:=a[j]; a[j]:=c;
       c:=t[i]; t[i]:=t[j]; t[j]:=c;
       c:=b[i]; b[i]:=b[j]; b[j]:=c;
       inc(i);
       dec(j);
     end;
 until i>j;
 if l<j then qsort(l,j);
 if i<r then qsort(i,r);
end;

begin
 read(n);
 start:=10000;
 for i:=1 to n do
   begin
     read(t[i],a[i],b[i]);
     if time<b[i] then time:=b[i];
     if start>a[i] then start:=a[i];
   end;

 for i:=start to time do
  f[i]:=maxlongint;

 qsort(1,n);
 f[start]:=0;

 for i:=start to time do
   begin
     check:=true;
     if f[i]<>maxlongint then
      for j:=1 to n do
       if (i+t[j]<=b[j])and(i>=a[j]) then
         begin
           check:=false;
           if f[i+t[j]]>f[i]+t[j] then f[i+t[j]]:=f[i]+t[j];
         end;
     if check then
      if f[i+1]>f[i] then f[i+1]:=f[i];
   end;
 write(f[time]);
end.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值