noip普及组复赛模拟试题14附答案.docx
- 文档编号:11835386
- 上传时间:2023-04-05
- 格式:DOCX
- 页数:13
- 大小:19.01KB
noip普及组复赛模拟试题14附答案.docx
《noip普及组复赛模拟试题14附答案.docx》由会员分享,可在线阅读,更多相关《noip普及组复赛模拟试题14附答案.docx(13页珍藏版)》请在冰豆网上搜索。
noip普及组复赛模拟试题14附答案
解的个数(count)
给定一个正整数K,问有多少和正整数X,Y满足X>=Y且1/K=1/X+1/Y,将所有解按X降序输出。
输入
第一行一个数T,表示数据组数
以下T行,每行一个数K
输出
T部分,每部分第一行一个数K,以下一次按X降序输出所有解,个数见样例,注意=+两边都有空格。
样例输入
2
2
12
样例输出
2
1/2=1/6+1/3
1/2=1/4+1/4
8
1/12=1/156+1/13
1/12=1/84+1/14
1/12=1/60+1/15
1/12=1/48+1/16
1/12=1/36+1/18
1/12=1/30+1/20
1/12=1/28+1/21
1/12=1/24+1/24
数据规模
30% K<=20
100% K<=10000,T<=10
标程:
vart,i,j,l,n,k:
integer;
a:
array[1..20]ofinteger;
b,c:
array[1..10000]oflongint;
procedureshou(n:
integer);
vark,s:
longint;
begin
k:
=n+1;s:
=n*2;l:
=0;
fori:
=ktosdo
begin
ifn*imod(i-n)=0then
begin
inc(l);
b[l]:
=(n*i)div(i-n);c[l]:
=i;
end;
end;
end;
begin
assign(input,'count.in');
reset(input);
assign(output,'count.out');
rewrite(output);
readln(t);
fori:
=1totdo
readln(a[i]);
fork:
=1totdo
begin
shou(a[k]);
writeln(l);
forj:
=1toldo
writeln(1,'/',a[k],'','=','',1,'/',b[j],'','+','',1,'/',c[j]);
end;
close(input);
close(output);
end.
输入
3
4
15
32
输出
3
1/4=1/20+1/5
1/4=1/12+1/6
1/4=1/8+1/8
5
1/15=1/240+1/16
1/15=1/90+1/18
1/15=1/60+1/20
1/15=1/40+1/24
1/15=1/30+1/30
6
1/32=1/1056+1/33
1/32=1/544+1/34
1/32=1/288+1/36
1/32=1/160+1/40
1/32=1/96+1/48
1/32=1/64+1/64
不等数列(num.cpp/c/pas)【题目描述】将1到n任意排列,然后在排列的每两个数之间根据他们的大小关系插入“>”和“<”。
问在所有排列中,有多少个排列恰好有k个。
答案对2012取模。
【输入格式】
第一行2个整数n,k。
【输出格式】
一个整数表示答案。
【样例输入】
52
【样例输出】
66
【数据范围】
对于30%的数据:
n<=10
对于100%的数据:
k 题解: 对于30%n<=10的数据,搜索打表,状态压缩动态规划...... 对于1--n等类似的排列计数问题,以动态规划和组合数学2种大方向为基本解决方向。 组合数学在noip最难也就到杨辉三角左右,所以这题我从动态规划展开。 如果此类排列问题在脑中的模型是: “有n个格子,填入1--n”,那么相对应的DP就不得不记录哪些数填过了(从左到右填入)或者哪些格子填过了(从小到大填入)。 这样一来就必须要使用状态压缩来存储这些信息,就使得复杂度变得难以接受。 而如果换个模型: “从小到大把数字插入数列”。 注意是数列而不是格子,这样一来就不需要记录是哪些数字插入了(而只要记录插入到了第几个数字),同时不需要记录每个数字的具体位置,也不需要记录数字的相对位置,而只需记录相对关系的数目(对本题而言就是有几个“<”)。 因为是从小到大插入数字,所以当前插入的数字一定大于所有已经插入的。 蓝色是当前插入的数字,如果它插入到<关系的2个数字之间(或者数列最左端),就会使数列的<数量不变,>数量+1: 类似的,插入到>关系的2个数字之间(或者数列最右端),数列的<数量+1,>数量不变。 F[i][j]表示前i个数字构成的数列中,恰有j个‘<’号的方案数(‘>’号就有i-j-1个)。 F[i][j]=F[i-1][j-1]*(i-j)+F[i-1][j]*(j+1). 时空复杂度: O(n^2) 若打表则时间复杂度为O (1) 【参考程序】 varn,k,i,j: integer; f: array[0..10001,0..1001]oflongint; begin assign(input,'num.in'); reset(input); assign(output,'num.out'); rewrite(output); readln(n,k); fori: =1tondo begin f[i,0]: =1; f[i,i-1]: =1; end; fori: =1tondo forj: =1tokdo begin ifj>=i-1thencontinue; f[i,j]: =(f[i-1,j-1]*(i-j)+f[i-1,j]*(j+1))mod2012; end; writeln(f[n,k]mod2012); close(input); close(output); end. 输入94输出1266 输入30012输出700 输入1000126输出612 商店老板给Ezio拿出了n件装备,每个装备有一个标号a,这n件装备排成一排,他要求Ezio从中剔除一些装备,使得剩下的装备在顺序不变的情况下成为一套,装备成为一套的条件是,每相邻的两件装备标号不互质。 他说如果Ezio能找出剩下装备最多的一套装备,他就把这套装备送给Ezio。 聪明的Ezio当然能够搞定。 不过他想知道最多能剩下多少装备。 输入input 第一行一个数n 第二行n个数,表示每件装备的标号a,每两个数之间用一个空格隔开,结尾无空格 输出output 一个整数,表示最多能剩下的装备数 样例输入sampleinput 6 6231545 样例输出sampleoutput 4 (只需删掉原序列中的2和4,即余下的序列为63155,每相邻两个不互质,故最多剩下4件。 ) 数据范围 对于30%数据n<=1000 对于100%数据n<=100000a<=10000 思路: 把a[i]分解质因数,用b数组记录前i-1个数中包含某个因子能组成的最长的序列的长度。 a[i]的k个因子s[1]到s[k] 找出 max(b[s[j]])然后把b[s[1]]到b[s[k]]都赋值为max+1。 最后找出 max(b[i]) 程序: var a: array[1..100000]oflongint; b,s: array[1..10000]oflongint; n,m,i,j,k,ans,max: longint; procedureinit; begin readln(n); fori: =1tondoread(a[i]); fillchar(b,sizeof(b),0); end; procedurefj(x: longint); var i,j: longint; begin max: =0; k: =0;i: =1; repeat inc(i); ifxmodi=0then begin inc(k); s[k]: =i; ifmax =b[i]; end; whilexmodi=0dox: =xdivi; untilx=1; forj: =1tokdo b[s[j]]: =max+1; end; proceduredoit; begin fori: =1tondofj(a[i]); ans: =0; fori: =1to10000do ifans =b[i]; writeln(ans); end; begin assign(input,'arm.in'); assign(output,'arm.out'); reset(input); rewrite(output); init; doit; close(input); close(output); end. 输入10 6923121548516输出7 输入34 1267653212565523169788564321248256866888874902555302485123956489010245093342073695661204524905512803456234542输出29 【问题描述】 某一村庄在一条路线上安装了n盏路灯,每盏灯的功率有大有小(即同一段时间内消耗的电量有多有少)。 老张就住在这条路中间某一路灯旁,他有一项工作就是每天早上天亮时一盏一盏地关掉这些路灯。 为了给村里节省电费,老张记录下了每盏路灯的位置和功率,他每次关灯时也都是尽快地去关,但是老张不知道怎样去关灯才能够最节省电。 他每天都是在天亮时首先关掉自己所处位置的路灯,然后可以向左也可以向右去关灯。 开始他以为先算一下左边路灯的总功率再算一下右边路灯的总功率,然后选择先关掉功率大的一边,再回过头来关掉另一边的路灯,而事实并非如此,因为在关的过程中适当地调头有可能会更省一些。 现在已知老张走的速度为1m/s,每个路灯的位置(是一个整数,即距路线起点的距离,单位: m)、功率(W),老张关灯所用的时间很短而可以忽略不计。 请你为老张编一程序来安排关灯的顺序,使从老张开始关灯时刻算起所有灯消耗电最少(灯关掉后便不再消耗电了)。 【输入】 文件第一行是两个数字n(0 接下来n行,每行两个数据,表示第1盏到第n盏路灯的位置和功率。 【输出】 一个数据,即最少的功耗(单位: J,1J=1W·s)。 【样例】 power.in power.out 53 270 {此时关灯顺序为34215,不必输出这个关灯顺序} 210 320 520 630 810 【参考程序】 const fi='powers.in'; fo='powers.out'; var N,C: integer; mem: array[1..50,0..1]ofinteger; tot,ans: longint; PROCEDUREInit; var i: integer; begin {assign(input,fi); reset(input);} readln(N,C); tot: =0; fori: =1toNdo begin readln(mem[i,0],mem[i,1]); tot: =tot+mem[i,1]; end; tot: =tot-mem[C,1]; close(input); ans: =maxlongint; end; PROCEDUREKernel(l,r,now: byte;jps,sum: longint); begin ifsum>ansthen exit; if(l=0)and(r=N+1)then begin ifsum ans: =sum; exit; end; ifl>=1then Kernel(l-1,r,l,jps-mem[l,1],sum+jps*(mem[now,0]-mem[l,0])); ifr<=Nthen Kernel(l,r+1,r,jps-mem[r,1],sum+jps*(mem[r,0]-mem[now,0])); end; PROCEDUREPrint; begin {assign(output,fo); rewrite(output);} writeln(ans); close(output); end; begin Init; ifN=1then begin ans: =0; Print; halt; end; Kernel(C-1,C+1,C,tot,0); Print; end. 输入 104 220 325 530 720 840 1035 1232 1326 1524 1836输出2959 输入207 235 426 528 618 920 1024 1225 1438 1540 1629 1837 1926 2033 2145 2341 2436 2548 2739 3026 3143输出11470
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- noip 普及 复赛 模拟 试题 14 答案