NOIP普及组复赛精彩试题源程序.docx
- 文档编号:11655469
- 上传时间:2023-03-29
- 格式:DOCX
- 页数:17
- 大小:25.06KB
NOIP普及组复赛精彩试题源程序.docx
《NOIP普及组复赛精彩试题源程序.docx》由会员分享,可在线阅读,更多相关《NOIP普及组复赛精彩试题源程序.docx(17页珍藏版)》请在冰豆网上搜索。
NOIP普及组复赛精彩试题源程序
标准文案
NOIP2011普及组复赛
1.数字反转(reverse.cpp/c/pas)
【问题描述】给定一个整数,请将该数各个位上数字反转得到一个新数。
新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零。
(参见样例2)
【输入】
输入文件名为reverse.in。
输入共一行,一个整数N。
【输出】
输出文件名为reverse.out。
输出共1行,一个整数,表示反转后的新数。
【输入输出样例1】
reverse.inreverse.out
321123
】2【输入输出样例
reverse.outreverse.in
-83
-380
【数据范围】≤-1,000,000,000N≤1,000,000,000。
,【解题】这道题非常简单,可以读字符串处理,也可以读数字来处理,只不过要注意符号问题(以及-0。
但测试数据没出)【法一】字符串处理Vari,l,k:
integer;
s:
string;
p:
boolean;
begin
reset(input);assign(input,'reverse.in');
rewrite(output);assign(output,'reverse.out');
readln(s);
l:
=length(s);
k:
=1;
ifs[1]='-'then
begin
write('-');
k:
=2;
end;
p:
=true;;
fori:
=ldowntokdo
大全.
标准文案
begin
if(p)and((s[i]='0'))thencontinue
else
begin
write(s[i]);
p:
=false;;
end;
end;
close(input);close(output);
end.
【法二】数字处理
Varf:
integer;
n,ans:
longint;
begin
assign(input,'reverse.in');reset(input);
assign(output,'reverse.out');rewrite(output);
readln(n);
ifn<0then
begin
f:
=-1;
n:
=-n;
end
else
f:
=1;
ans:
=0;
whilen<>0do
begin
ans:
=ans*10+nmod10;
n:
=ndiv10;
end;
ans:
=ans*f;
writeln(ans);
close(input);close(output);
end.
2.统计单词数(stat.pas/c/cpp)
【问题描述】
一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数。
大全.
标准文案
现在,请你编程实现这一功能,具体要求是:
给定一个单词,请你输出它在给定的文章中出现的次数和第一次出现的位置。
注意:
匹配单词时,不区分大小写,但要求完全匹配,即给定单词必须与文章中的某一独立单词在不区分大小写的情况下完全相同(参见样例1),如果给定单词仅是文章中某一单词的一部分则不算匹配(参见样例2)
【输入】输入文件名为stat.in,2行。
第1行为一个字符串,其中只含字母,表示给定单词;
第2行为一个字符串,其中只可能包含字母和空格,表示给定的文章。
【输出】输出文件名为stat.out。
只有一行,如果在文章中找到给定单词则输出两个整数,两个整数之间用一个空格隔开,
分别是单词在文章中出现的次数和第一次出现的位置(即在文章中第一次出现时,单词首字
母在文章中的位置,位置从0开始);如果单词在文章中没有出现,则直接输出一个整数-1。
【输入输出样例1】
stat.instat.out
20
To
tobeornottobeisaquestion
解释】【输入输出样例1。
To在文章中出现两次,第一次出现的位置为0输出结果表示给定的单词
】【输入输出样例2
stat.in1052015
stat.out
to
DidtheOttomanEmpireloseitspoweratthattime【输入输出样例说明】
-1
解释】【输入输出样例2。
表示给定的单词to在文章中没有出现,输出整数-110【数据范围】1≤单词长度≤。
1≤文章长度≤1,000,000。
【解题】这道题也不是很难,programstat;
varI,n,p:
longint;
s,s1:
string;
c:
char;
begin
reset(input);assign(input,'stat.in');
rewrite(output);assign(output,'stat.out');
readln(s);
string,也可为//函数upcase()参数可为chars:
=upcase(s);
0//i统计读入的字符位置,首个字符出现的位置是i:
=-1;
//s1累加读入的字符s1:
='';
//nn:
=0;统计出现次数//p标记第一次出现的位置p:
=-1;
repeat
read(c);
大全.
标准文案
c:
=upcase(c);//统一大小写
i:
=i+1;
ifc=''then//遇到空格,匹配是否相同
begin
ifs=s1then
begin
n:
=n+1;
ifp=-1then//p标记第一次出现的位置,如果p是第一次更改,记录位置
p:
=i-length(s);
end;
s1:
='';
end
else
s1:
=s1+c;//不是空格,继续叠加
untileoln(input);
ifs1=sthen//处理最后一个单词是否相同的情况
begin
n:
=n+1;
ifp=-1then
p:
=i-length(s)+1;//最后没有空格
end;
ifn=0thenwriteln(-1)
elsewriteln(n,'',p);
close(input);close(output);
end.
3.瑞士轮(swiss.cpp/c/pas)
【背景】
在双人对决的竞技性比赛,如乒乓球、羽毛球、国际象棋中,最常见的赛制是淘汰赛和循环赛。
前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高。
后者的特点是较为公平,偶然性较低,但比赛过程往往十分冗长。
本题中介绍的瑞士轮赛制,因最早使用于1895年在瑞士举办的国际象棋比赛而得名。
它可以看作是淘汰赛与循环赛的折衷,既保证了比赛的稳定性,又能使赛程不至于过长。
【问题描述】
2*N名编号为1~2N的选手共进行R轮比赛。
每轮比赛开始前,以及所有比赛结束后,都会按照总分从高到低对选手进行一次排名。
选手的总分为第一轮开始前的初始分数加上已参加过的所有比赛的得分和。
总分相同的,约定编号较小的选手排名靠前。
每轮比赛的对阵安排与该轮比赛开始前的排名有关:
第1名和第2名、第3名和第4名、……、第2K–1名和第2K名、……、第2N–1名和第2N名,各进行一场比赛。
每场比赛胜者得1分,负者得0分。
也就是说除了首轮以外,其它轮比赛的安排均不能事先确定,而是要取决于选手在之前比赛中的表大全.
标准文案
现。
现给定每个选手的初始分数及其实力值,试计算在R轮比赛过后,排名第Q的选手编号是多少。
我们假设选手的实力值两两不同,且每场比赛中实力值较高的总能获胜。
【输入】
输入文件名为swiss.in。
输入的第一行是三个正整数N、R、Q,每两个数之间用一个空格隔开,表示有2*N名选手、R轮比赛,以及我们关心的名次Q。
第二行是2*N个非负整数s,s,…,s,每两个数之间用一个空格隔开,其中s表示编号为i的选i2N21手的初始分数。
第三行是2*N个正整数w,w,…,w,每两个数之间用一个空格隔开,其中w表示编号为i的选i212N手的实力值。
【输出】
输出文件名为swiss.out。
输出只有一行,包含一个整数,即R轮比赛结束后,排名第Q的选手的编号。
【输入输出样例】
swiss.inswiss.out
1
242
7667
本轮对阵
本轮结束后的得分
选手编号
/
①
②
③
④
初始
/
7
6
6
7
第1轮
①—④②—③
7
6
7
8
第2轮
④—①③—②
7
6
8
9
第3轮
①—②④—③
8
6
9
9
轮第4
①—②③—④
9
6
10
9
【数据范围】100;≤对于30%的数据,1N≤≤10,000;N50%对于的数据,1≤8≤,2N0…,,s≤s,s≤≤,≤≤,≤≤的数据,对于100%1N100,0001R501Q10,w1,≤…,,w2N21218≤w10。
2N
【解题】题目虽然长,但理解题意后就发现解题的瓶颈在于排序。
)(如果每一轮比赛的结果都进行快速排序,时间复杂度为ORlongn,但事实证明这样只能拿分。
60,这需要一个巧算法:
分析得知,快速排序实际上进行了许多无用的工作:
AC如何轮是一样的;反之,如果两人都输了,轮后的先后关系与第i-1i轮都赢了,那么第i如果两个人在第他们的先后关系也不会变。
个赢者(他们的先所以,我们有一个新算法:
一开始做一趟快速排序,然后对于每一轮,将此轮的n个输者(他们的先后关系和上一轮也不变分开,然后就是归并,于是时间复杂后关系和上一轮不变)和n(度O)Rn)次,必然结果是超时。
事实上只需一次真正意义上的排序以后,在以r(实践证明,如果单纯的排序大全.
标准文案
后的比赛中,按原顺序分成两组,获胜组和失败组,这两组依然是有序的,再把这两组归并成一组,就可以了。
总时间复杂度O(N*R))
programswiss;
vara,b,v:
array[1..200000]oflongint;
c,d:
array[1..100000,1..2]oflongint;
n,r,q,i,j:
longint;
procedureqsort(l,r:
longint);
vari,j,mid1,mid2,t:
longint;
begin
i:
=l;j:
=r;mid1:
=a[(l+r)div2];mid2:
=v[(l+r)div2];
repeat//按分数从高到低排序,分数相同的,编号较小的选手排名靠前
while(a[i]>mid1)or(a[i]=mid1)and(v[i] while(a[j] ifi<=jthen begin t: =a[i];a[i]: =a[j];a[j]: =t; t: =v[i];v[i]: =v[j];v[j]: =t; inc(i);dec(j); end; untili>j; ifi ifl end; proceduremergesort;//归并排序 vari,l1,l2: longint; begin i: =0; l1: =1; l2: =1; repeat if(c[l1,1]>d[l2,1])or(c[l1,1]=d[l2,1])and(c[l1,2] begin i: =i+1; a[i]: =c[l1,1]; v[i]: =c[l1,2]; l1: =l1+1; end else 大全. 标准文案 begin i: =i+1; a[i]: =d[l2,1]; v[i]: =d[l2,2]; l2: =l2+1; end; until(l1>n)or(l2>n); whilel1<=ndo begin i: =i+1; a[i]: =c[l1,1]; v[i]: =c[l1,2]; l1: =l1+1; end; whilel2<=ndo begin i: =i+1; a[i]: =d[l2,1]; v[i]: =d[l2,2]; l2: =l2+1; end; end; begin//主程序 assign(input,'swiss.in');reset(input); assign(output,'swiss.out');rewrite(output); readln(n,r,q); fori: =1ton*2doread(a[i]);//数组a保存初始分数 fori: =1ton*2doread(b[i]);//数组b保存实力值 fori: =1ton*2dov[i]: =i;//数组v[i]保存排名第i的选手编号 qsort(1,2*n); fori: =1tordo begin forj: =1tondo ifb[v[2*j-1]]>b[v[2*j]]then begin inc(a[2*j-1]); c[j,1]: =a[2*j-1];//数组c[j,1]保存嬴方的总分;数组c[j,2]保存嬴方的号码; c[j,2]: =v[2*j-1]; d[j,1]: =a[2*j];//数组d[j,1]保存输方的总分;数组d[j,2]保存输方的号码; d[j,2]: =v[2*j]; 大全. 标准文案 end else begin inc(a[2*j]); c[j,1]: =a[2*j]; c[j,2]: =v[2*j]; d[j,1]: =a[2*j-1]; d[j,2]: =v[2*j-1]; end; mergesort; end; writeln(v[q]); close(input);close(output); end. 4.表达式的值(exp.cpp/c/pas) 【问题描述】 对于1位二进制变量定义两种运算: 运算符 运算规则 ⊕ ⊕0=00⊕1=10⊕0=11⊕11=1 × 0=00×1=00× 0=01× ×1=11 运算的优先级是: 1.先计算括号内的,再计算括号外的。 先计算×运算,再计算⊕运算。 2.“×”运算优先于“⊕”运算,即计算表达式时,做⊕运算。 C,其结果再与AB例如: 计算表达式A⊕B×C时,先计算×请问有多少种填法可以使,0或者1现给定一个未完成的表达式,例如_+(_*_),请你在横线处填入数字得表达式的值为0。 【输入】2行。 输入文件名为exp.in,共的运算符和括号的个数。 行为一个整数L,表示给定的表达式中除去横线外第1 种字符,其中'*个字符,其中只包含'('、')'、'+'、''这4L2第行为一个字符串包含'分别表示前面定义的运算符“⊕”和“×”。 这行字符按顺序*+('、')'是左右括号,''、'给出了给定表达式中除去变量外的运算符和括号。 大全. 标准文案 【输出】 输出文件exp.out共1行。 包含一个整数,即所有的方案数。 注意: 这个数可能会很大, 请输出方案数对10007取模后的结果。 【输入输出样例1】 exp.inexp.out 3 4 +(*) 【输入输出样例说明】_+(_*_) 给定的表达式包括横线字符之后为: 种填法。 时,表达式的值均为0,所以共有31、0)、(0、0、1)、在横线位置填入(00、0)、(0、【数据范围】≤≤L10。 对于20%的数据有0L≤1,000。 对于50%的数据有0≤L≤10,000。 对于70%的数据有0≤≤100,000。 L对于100%的数据有0≤50%的数据输入表达式中不含括号。 对于【解题】表示表0的方案数,f(s,1)一个符号栈,两个数据栈。 记f(s,0)表示表达式s为算法类似于表达式计算,为1的方案数。 达式sf(a+b,0)=f(a,0)*f(b,0) f(a+b,1)=f(a,0)*f(b,0)+f(a,0)*f(b,1)+f(a,1)*f(b,0) f(a*b,0)=f(a,0)*f(b,0)+f(a,1)*f(b,0)+f(a,0)*f(b,1) f(a*b,1)=f(a,1)*f(b,1) programexp; maxn=100010; const op: array[1..4]ofchar=('(','+','*',')'); ('<','<','<','='),flag: array[1..4,1..4]ofchar=({(} ('<','>','<','>'),{+} ('<','>','>','>'), {*} //符号优先级表('>','>','>','>'));{)} stack_op: array[1..maxn]ofchar; var stack_data0,stack_data1: array[1..maxn]oflongint; n,top_op,top_data,i,len: longint; a0,a1,b0,b1,t0,t1: longint; ; s: ansistring ch,now: char; procedurepush_op(ch: char);//运算符压栈begin inc(top_op); 大全. 标准文案 stack_op[top_op]: =ch; end; functionpop_op: char;//运算符出栈 begin pop_op: =stack_op[top_op]; dec(top_op); end; functiongettop: char;//取栈顶符号 begin gettop: =stack_op[top_op]; end; procedurepush_data(a0,a1: longint);//数据压栈 begin inc(top_data); stack_data0[top_data]: =a0; stack_data1[top_data]: =a1; end; procedurepop_data(vara0,a1: longint);//数据出栈 begin a0: =stack_data0[top_data]; a1: =stack_data1[top_data]; dec(top_data); end; functionfind(ch: char): integer;//读入符号 vari: longint; begin fori: =1to4do ifop[i]=chthenexit(i); end; begin assign(input,'exp.in');reset(input); assign(output,'exp.out');rewrite(output); top_op: =0;top_data: =0;//top_op运算符栈顶指针;top_data数据栈顶指针 push_op('(');push_data(1,1);//压栈 readln(n); 大全. 标准文案 readln(s); s: =s+')'; len: =length(s); i: =1; whilei<=lendo begin ifi=22then readln; caseflag[find(gettop),find(s[i])]of '<': begin push_op(s[i]);//运算符出栈 if(s[i]<>'(')thenpush_data(1,1);//数据出栈 inc(i); end; '=': beginnow: =pop_op;inc(i);end; '>': begin pop_data(a0,a1); pop_data(b0,b1); now: =pop_op; ifnow='+'then begin t0: =(a0*b0)mod10007; t1: =((a0*b1)mod10007+(a1*b1)mod10007+(a1*b0)mod10007)mod 10007; push_data(t0,t1); end else begin t0: =((a0*b1)mod10007+(a1*b0)mod10007+(a0*b0)mod10007)mod 10007; t1: =(a1*b1)mod10007; push_data(t0,t1); end; end; end; end; writeln(stack_data0[top_data]); close(input);close(output); end. 大全.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- NOIP 普及 复赛 精彩 试题 源程序