当前位置:首页 > 2013年慈溪市小学生计算机程序设计竞赛复赛试题解题报告
4个小朋友参加转圈游戏,转圈共进行了1轮,在这轮转圈游戏中,所有小朋友依次向顺时针方向转了3个位置,第0号小朋友转到第3号位置,第1号小朋友转到了第0号位置,第2号小朋友转到了第1号位置,第3号小朋友转到了第2号位置,所以最后第0号位置到第3号位置上的小朋友编号分别是1,2,3,0。 【输入输出样例2】 circle.in 5 3 1 1 2 2 1 3
circle.out 2 3 4 0 1
【样例2解释】
5个小朋友参加转圈游戏,转圈共进行了3轮。在第1轮转圈游戏中,所有小朋友依次向逆时针方向转了1个位置。在第2轮转圈游戏中,所有小朋友依次向顺时针方向转了2个位置。在第3轮转圈游戏中,所有小朋友依次向逆时针方向转了3个位置。所以最后第0号位置到第4号位置上的小朋友编号分别是2,3,4,0,1。 【数据范围约定】
对于70%的数据,1≤n≤1000,0≤q≤2000。
对于100%的数据,1≤n≤100000,0≤q≤200000。 【问题分析】
求n个人按输入规则进行q轮转圈后,每个位置上的人对应的编号。 【算法分析】
模拟,只要统计出每个人最后相当于逆时针转了多少距离即可。 【参考程序】
var x,i,v,n,m,a,b:longint;
begin
assign(input,'circle.in'); reset(input);
assign(output,'circle.out'); rewrite(output); read(n,m); for i:=1 to m do begin read(a,b);
if a=1 then v:=(v-b) mod n else v:=(v+b) mod n; end;
for i:=0 to n-1 do begin
x:=(i-v) mod n;
while x<0 do x:=x+n;
writeln(x); end;
close(input); close(output); end.
3.排队(queue.pas)
【问题描述】
按身高排队是我们最常用的一种排队方法,一伙小朋友已经非常厌倦了这种排队方式,这次他们打算按每个人的姓名排队,但如果按照姓名的字典序进行排队似乎有点麻烦,所以他们找了一种比较简单的排队方法:根据姓名的长度进行排队,姓名长的排在最前面,姓名短的排在最后面。
姓名的长度他们有这样的约定:每个人的姓名只能由“a”( ASCII码为97)到“z” (ASCII码为122)这26个小写英文字母构成,姓名的长度就是姓名中字母的总个数。 由于小朋友人数比较多,请根据他们的排队方法,编程帮助他们排队吧! 【输入数据】
输入文件queue.in:输入从文件中读取,输入共n+1行。 第1行是一个整数n(1≤n≤15000),表示总共有n个小朋友参加排队(编号为1到n)。 第2行到第n+1行,每行一个字符串,其中第i+1行表示第i 个小朋友的姓名,数据保证每个小朋友都有姓名,并且姓名的长度不超过255。 【输出数据】
输出文件queue.out:结果输出到文件中。
输出共n行,表示经过排队后的小朋友的姓名情况,姓名长的先输出,姓名短的后输出。注意,当小朋友的姓名长度一样时,输出的顺序同输入的顺序(参考样例解释)。 【输入输出样例】 queue.in 3
aoteman guaishou jiqiren queue.out guaishou aoteman jiqiren
【样例解释】
有3个小朋友参加了排队,第1个小朋友的姓名长度为7,第2个小朋友的姓名长度为8,第3个小朋友的姓名长度为7。因为第2个小朋友的姓名最长,所以最先输出,第1个小朋友和第3个小朋友的姓名长度都为7,但在输入中,小朋友“aoteman”在小朋友“jiqiren”的前面,所以先输出“aoteman”,然后输出“jiqiren”。 【数据范围约定】
60%的输入数据保证1≤n≤1000,且每个小朋友的姓名长度不超过100。 80%的输入数据保证1≤n≤8000,且每个小朋友的姓名长度不超过255。 100%的输入数据保证1≤n≤15000,且每个小朋友的姓名长度不超过255。 【问题分析】
给出一些字符串,按要求进行排序。
【算法分析】
排序,可采用双关键字快排。 【参考程序】 var n,i:longint;
a,b:array[1..15000] of longint; s:array[1..15000] of string;
procedure sort(l,r:longint); var i,j,t,mid,m:longint; begin
i:=l; j:=r; mid:=a[(i+j) div 2]; m:=b[(i+j) div 2]; repeat
while (a[i]>mid) or (a[i]=mid) and (b[i]
t:=a[i]; a[i]:=a[j]; a[j]:=t; t:=b[i]; b[i]:=b[j]; b[j]:=t; inc(i); dec(j); end; until i>j;
if l begin assign(input,'queue.in'); reset(input); assign(output,'queue.out'); rewrite(output); readln(n); for i:=1 to n do begin readln(s[i]); a[i]:=length(s[i]); b[i]:=i; end; sort(1,n); for i:=1 to n do writeln(s[b[i]]); close(input); close(output); end. 4.寻找子矩阵(matrix.pas) 【问题描述】 一个由n行m列构成的矩阵(从上到下对行1到n编号,从左到右对列1到m编号), 第i 行第j 列中有一个正整数Wij。例如下面是一个3行4列的矩阵。 现在从中选取一个p行q列的子矩阵,例如下面黑框中选取的是一个2行3列的子矩阵。 仔细观察会发现,从上面的矩阵中选取2行3列的子矩阵共有4种不同的方法。 现在请你找这样一个子矩阵,满足以下条件: 将子矩阵的q列从左到右编号为1到q,删除子矩阵中所有编号为奇数的列,或者删除子矩阵中所有编号为偶数的列,然后 用子矩阵中剩下的数之和 减掉 子矩阵中被删除的数之和,得到一个结果S,S最大的子矩阵就是我们要找的子矩阵,注意,这样的子矩阵可能有多个。 例如上面黑框中的子矩阵,删除编号为奇数的列(下图1)或删除编号为偶数的列(下图2)。(阴影部分为删除的列) 按照计算规则,图1中剩下的数之和为8,被删除的数之和为9,所以S=-1,图2中剩下的数之和为9,被删除的数之和为8,所以S=1,也就是说当选择这个子矩阵时,S的最大值为1。当然可以选择其他子矩阵来获取更大的S。 【输入数据】 输入文件matrix.in:输入从文件中读取,输入共n+1行。 第一行包含 4 个整数 n、m、p、q (1≤n,m≤1000,1≤p≤n,1≤q≤m),每两个整数之间用一个空格隔开。 接下来n行,每行包含 m 个整数。第i+1行的第j 个整数为Wij(1≤Wij≤100),表示矩 阵中的第i 行第j 列的数,每两个整数之间用一个空格隔开。 【输出数据】 输出文件matrix.out:结果输出到文件中。 输出共一行,包含一个整数,表示最大的S。注意不需要输出你选择的子矩阵。 【输入输出样例】 matrix.in 3 4 2 3 1 5 2 3
共分享92篇相关文档