Noip 2010普及组解题报告

  • 格式:docx
  • 大小:17.13 KB
  • 文档页数:5

解析

1、 数字统计

【思路分析】

这道题属于简单题,用一个FOR把数都检查一遍,里面再用while剥皮看看有多少个2。

【参考程序】

Var

I,n,l,r,s:integer;

Begin

Assign(input,’two.in’);

Assign(output,’two.out’);

Readln(l,r);

S:=0;

For i:=1 to r do

Begin

N:=I;

While n>0 do

Begin

If n mod 10=2 then s:=s+1;

N:=n div 10;

End;

End;

Writeln(s);

Close(input);close(output;)

End.

2、 接水问题

【思路分析】

方法一:用一个数组,存放每个水龙头当前还需要多少时间装完这桶水;然后一个一个人去轮,每次找最快装完的水龙头,接着把当前轮到的那个人所需要的时间加到格子里;最后轮完以后,还要把数组里的最大值输出。

【参考程序】

Var

a:=array[1..10000]of integer;

b:=array[1..100]of longint;

m,n,i,k,t,max,min:longint;

begin

assign(input,'water.in');

assign(output,'water.out');

reset(input);rewrite(output);

readln(n,m);

for i:=1 to n do read(a[i]);

fillchar(b,sizeof(b),0);

max:=0;k:=1;

while(k<=n) do

begin min:=maxlongint;t:=0;

for i:=1 to m do

if b[i]

min:=b[i];

t:=i;

end;

b[t]:=b[t]+a[k];

k:=k+1;

if b[t]>max then max=b[t];

end;

writeln(max);

close(input);close(output);

end.

方法二:用一个数组,存放每个水龙头当前还需要多少时间装完这桶水,并按照时间长短从大到小安排好;然后一个一个去轮,显然最快装完的 水龙头总是最后一个,这样只要把当前轮到的那个人所需的时间加到最后那个元素里,再把数组排序好(很明显,这里要用插入排序效率最高);最后只要输出数组第一个元素就可以了。

【参考程序】

Var

a:=array[1..10000]of integer;

b:=array[1..100]of longint;

m,n,i:integer;

procedure sort(x:longint);

var i,j:integer;

begin

j:=m-1;

while(j>0)and(b[j]

for i:=m-1 downto j+1 do

b[i+1]:=b[i];

b[j+1]=x;

end;

begin

assign(input,'water.in');

assign(output,'water.out');

reset(input);rewrite(output);

readln(n,m);

for i:=1 to n do read(a[i]);

fillchar(b,sizeof(b),0);

for i:=1 to n do

begin

b[m]:=b[m]+a[i];

sort(b[m]);

end; writeln(b[1]);

close(input);close(output);

end.

3.导弹拦截

【思路分析】

先算出没课导弹到两个系统的距离的平方,存入相应的数组,并按照到第一套系统的距离的平方从大到小排序好(本题最大数据有100000组,故需要用快速排序,否则会超时);再以第二套系统出发,刷新他的平方(如果新半径平方比旧的要大的话)。注意,这题不用开放,因为开放以后再平方等于什么也没有做。

【参考程序】

var

a,b:array[1..100000]of longint;

x,y,x1,y1,x2,y2,n,min,i,max:longint;

procedure kp(1,r:longint);

var i,j,t1,t2:longint;

begin

i:=1;j:=r;t1:=a[i];t2:=b[i];

while i

begin

while(i

if i

begin

a[i]:=a[j];b[i]:=b[j];inc(i) end;

while (it1) do inc(i)

if i

b[j]:=b[i];dec(j) end

end;

a[i]:=t1;b[i]:=t2;

if l

if j+1

end;

begin

assign(input,'missile.in');

assign(output,'missile.out');

reset(input);rewrite(output);

readln(x1,y1,x2,y2);

readln(n);

for i:=1 to n do

begin

readln(x,y);

a[i]:=(x-x1)*(x-x1)+(y-y1)*(y-y1);

b[i]:=(x-x2)*(x-x2)+(y-y2)*(y-y2);

end;

kp(1,n); min:=a[1];max:=0;

for i:=1 to n-1 do

begin

if b[i]>max then max:=b[i];

if a[i+1]+max

end;

writeln(min);

close(input);close(output);

end.

4.三国游戏

【思路分析】

这道题是一道比较忽悠人的题。

我的程序的策略是:建立武将默契值的二维数组,对行或者列进行排序,让后找出每行或者列的第二个数中的最大值即为结果。

注意要用快排,如果用选择排序或者冒泡排序的话要超时。我试了一下,不用快排能得90分。

小涵选一个将,计算机选一个将,小涵选将策略总是选武将默契值最大的两个将中的一个,而计算机总是将另一个将选走,然后小涵选与刚刚选中武将的默契值第二大的一个。

那么小涵从哪个武将开始选呢,选的武将的与其他武将的默契值第二大的数,比其他武将开始选默契值大二大的数最大的那个武将。

存在必胜策略。

【参考程序】

type arraytype=array[1..500,1..500] of longint;

var m,n,i,j,max,temp,l,k:longint;

a:arraytype;

procedure qsort(var a:arraytype;hang,lx,rx:longint);

var i,j,x,temp:longint;

begin

i:=lx;

j:=rx;

x:=a[hang,(i+j) div 2];

while i<=j do

begin

while a[hang,i]>x do inc(i);

while a[hang,j]

if i<=j then begin

temp:=a[hang,i];a[hang,i]:=a[hang,j];a[hang,j]:=temp;

inc(i);dec(j);end;

end;

if j>lx then qsort(a,hang,lx,j);

if i

end;

begin assign(input,'sanguo.in');

assign(output,'sanguo.out');

reset(input);

rewrite(output);

read(n);

for i:=1 to n-1 do

for j:=i+1 to n do

begin

read(a[i,j]);

a[j,i]:=a[i,j];

end;

for i:=1 to n do

qsort(a,i,1,n);

for i:=1 to n do

if a[i,2]>max then max:=a[i,2];

writeln(1);

write(max);

close(input);

close(output);

end.