一、聪明的小李
提交文件: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]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]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 lthen qsort(l,j);
if ithen qsort(i,r);
end;
begin
read(n);
start:=10000;
for i:=1 to n do
begin
read(t[i],a[i],b[i]);
if timethen 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.