當前位置:歷史故事大全網 - 歷史天氣 - noip2009普及组复赛解题报告

noip2009普及组复赛解题报告

产出方式产出

问题转述:

给出一元产出方式的各项指标和比例,按照规定的格式要求产出产出方式。

分析:

普及组的水题。演示式大家应该很熟悉,输出的时候注意一下几点即可:

1. 最高次项为正的话底层无加号。

2. 系数为0不输出。

3. 一次项输出x,不是x^1。

4. 非常数项系数为1或-1时直接输出正负号,其余项需要输出该数字。

其中第三项外勤护士在样例中检查出错误,但若自动到第三点那么就只能得到50分了。

程序:

var i,k,n:longint;

begin

分配(输入,'poly.in');重置(输入);

分配(输出,'poly.out');重写(输出);

readln(n);

for i:=n downto 0 do

begin

read(k);

if k= 0则继续;

if (kgt;0) and (ilt;gt;n) then write(' ');

if i=0 then write(k)

else if (abs(k)lt;gt;1) then write(k) else if k=-1 then write('-');

if ilt;gt;0 then

if i=1 then write('x')

else write('x^',i);

end;

writeln;

关闭(输入);

关闭(输出);

结束。

2009-11-28 12:03回复

自杀猫

0位粉丝

3楼

分数线划定

问题转述:

给出录取人数及所有面试者成绩、考号。求出分数线和实际录取人数,并按成绩降序,若成绩相同则考号升序的规则输出录取者考号与成绩。

分析:

双关键字排序。由于n在5000左右,为了保证不TLE所以需要使用快排等nlogn的排序。之后将指针指向计划分配的最后一只,并滑动至相同份额的最后一人。则指针之前为实际录取的面试者。

程序:

输入arr=array;temp1:=a;

重复

while (agt;temp1) or (( a=temp1) 和 (alt;temp2)) 执行 inc(i);

while (alt;temp1) 或 ((a=temp1) 和 (agt;temp2)) 执行 dec(j);

if ilt;=j then

开始

swap(a[i],a[j]);

inc( i);dec(j);

结束;

直到igt;j;

如果ilt;r则qsort(i,r);

p>

if jgt;l then qsort(l,j);

结束;

开始

随机化;

分配(输入,'score.in');重置(输入);

分配(输出,'score.out');重写(输出);

readln(n, m);

m:=trunc(m*1.5);

对于 i:=1 到 n 执行 readln(a,a);

a :=0;

qsort(1,n);

i:=m;

当a=a时做inc(i);

writeln(a,' ',i);

for j:=1 to i do

writeln(a,' ',a);

关闭(输入);关闭(输出);

结束。

2009-11-28 12:04 回复

自杀猫

0位粉丝

4楼

细胞分裂

问题转述:

给出m1,m2以及几个个si,求si^a mod m1^m2=0中a的简单。若无解,输出-1。

分析:

数学题。由于m1lt;= 30000,m2lt;=10000,根本无法直接计算,所以需要通过数学分析得出答案。如果一个数能够整除另一个数,那么这个数因数串联后一定有另一个数的所有元素,且每个元素个数均大于等于另一个数相同元素的个数。因此我们可以先对m1进行因数串联,把对应元素的个数乘以m2。之后读取每个数,判断该数因数串联后是否有m1中所有的元素。如果有的话,则计算该细胞最大的分裂次数,即对应m1种元素个数/si中元素个更新数后向上取整。最后答案即可。

注意原因数划分中1比较特殊,所以要单独判断一下。

程序:

输入 arr=array:=i;

a:=0;

while k mod i=0 do

开始

inc(a);

k:=k div i;

结束;

结束;

直到k=1;

结束;

程序main;

var i,z,max:longint;

开始

max:=-1;

read(k);

for i:=1 总共做

开始

if k mod alt;gt;0 然后退出;

z:=0;

while k mod a=0 do

开始

inc(z);

k:=k div a;

结束;

if (a z-1) div zgt;max then max:=(a z-1) div z;

end;

if maxlt;ans then ans:=max;

结束;

开始

分配(输入,'cell.in');重置(输入);

分配(输出, 'cell.out');rewrite(output);

ans:=maxlongint;

readln(n);

readln(m1,m2);

如果 m1=1 则开始 writeln(0);close(input);close(output);halt;end;

因式分解(m1,a,total);

p>

for i:=1总共做a:=a*m2;

for i:=1到n做

main;

if ans=maxlongint then writeln(-1) else writeln(ans);

关闭(输入);

关闭(输出);

结束。

2009-11-28 12:05 回复

自杀猫

0位粉丝

5楼

道路游戏

问题转述:

有一条环形路,路上有n个点,第i个点和第i个点有边相连(第n个点与第1个点有边完整)。每个点都可以花费不同的代价生产一个机器人,且机器人可以顺时针走不了于p步(每走一步耗费一单位时间),并捡起此时路上的金币。最多只能有一个机器人在路上。不同的时间每条路上金币数不同。求最后能够得到的最大金币数。(即捡起的金币数减少生产机器人需要的金币存在数)。

分析:

题目描述精准的吃饭,整理好思绪之后便应该能想出本题是动态规划。

由于高达1000的m,n,所以只能设计时间复杂度为O(mn)的动规。此类问题的动规模型比较好想,即:

其中f[i,j Coin[i,j]为i时间j号路得到的金币数。Cost[k]代表在k点购买机器人花费的金币数。其中1lt;=klt ;=n。step[i,j]代表f[i,j]的状态时机器人已经走的步数。past[j]为j之前的点。即past[i]=i-1(2lt;= ilt;=n)过去[1]=n。

注意这个动规是三维的,但是因为上一阶段的最优值是不变的,所以我们只需要在本阶段计算之后顺便保留一个最大的最优化值,作为下一级的上一级最优化值即可。

程序:

var i,j,k,n,m,p,pastmax,nowmax:longint;

coin,f,step:array[ 0..1000,0..1000] of longint;

cost,past:array[1..1000] of longint;

开始

赋值(输入,'game.in');重置(输入);

分配(输出,'game.out');重写(输出);

filldword(step,sizeof (步长) shr 2,maxlongint);

readln(n,m,p);

for i:=2 to n do

past[i ]:=i-1;

past[1]:=n;

对于 i:=1 到 n

对于 j:=1 到m do

read(coin[j,i]);

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

pastmax :=0;

for i:=1 to m

begin

nowmax:=-maxlongint;

for j: =1到n做

开始

if step[i-1,past[j]]lt;p then

开始

if pastmax-cost[past[j]]gt;f[i-1,past[j]]

则开始步骤[i,j]:=1;f[i,j]: =pastmax-cost[past[j]] coin[i,past[j]];结束

else begin 步骤[i,j]:=step[i-1,past[j]] 1 ;f[i,j]:=f[i-1,past[j]] coin[i,past[j]];end;

end

else 开始步骤[i,j]:=1;f[i,j]:=pastmax-cost[past[j]] coin[i,past[j]];end;

if f[i, j]gt;nowmax 那么 nowmax:=f[i,j];

end;

Pastmax:=nowmax;

end;

writeln(nowmax);

关闭(输入);

关闭(输出);

结束。

  • 上一篇:桂林景點介紹
  • 下一篇:螺旋傳動都有哪些分類?
  • copyright 2024歷史故事大全網