1. 【成绩处理】(3+3+3+3+3=15分)
笑笑最崇拜她的信息学Mr chen,这不,Mr chen正在教笑笑pascal语言中的记录类型:
有时候我们会遇到这种数据,它由性质各不相同的成分组成,例如:
学号 字符串类型
姓名 字符串类型
年龄 整型
性别 字符型
成绩 实型
如果用5个变量来存储,就失去了一个整体性,Pascal给我们提供了一种叫做记录的结构类型。在一个记录中,可以包含不同类型的并且互相相关的一些数据。
记录的定义:(如上面的数据定义如下)
type node=record
num:string;{学号}
name:string;{姓名}
age:integer;{年龄}
sex:string[6];{性别}
score:real;{成绩}
end;
var student:array[1..100] of node;{定义student数组的每个元素为node这种记录类型,该记录类型包含5个域}
记录的引用:
对记录中每个域的引用,如输入第i个学生的学号,有两种方法:(1)可以写出记录变量名和域名,pascal语言表示为readln(student[i].num);(2)使用开域语句with…do,pascal语言表示为 with student[i] do
Readln(num)
笑笑立马就掌握了这种数据结构,为了在你面前炫耀,她出了一个记录类型的题目考考你,给出n(1<=n<200)个同学m(1<=m<=5)科的考试成绩,按总分找出前十名是哪些同学。规定:总分相同名次相同,且占用后面的名次,例如:第2名有两个同学,那么将没有第3名,后面的同学将从第4名算起。
Input
第一行为n和m,下面n行为每个同学的成绩描述: 每行有m+1个数,其中第一个数为学号(小于等于200),后面为各科成绩,成绩为0~100之间的实数,中间用一个空格隔开。
Output
一行,成绩名次在前10的同学学号,不足10名全部输出。当第10名有多个同学时,输出有可能超过10名同学的学号。同名次按学号由小到大输出。输出的各个学号之间用一个空格隔开。
【输入样例】
17 2
1 7 13
2 18 54
3 47 91
4 65 86
5 44 48
6 92 88
7 80 36
8 76 68
9 54 21
10 65 11
11 61 69
12 78 32
13 0 81
24 93 32
15 42 97
16 28 9
17 65 55
【输出样例】
6 4 8 15 3 11 24 17 7 12
program test_2012_6;
type cj=array[1..5] of real;
rec=record
num:integer; //学号
s:cj; //考试科目成绩
m1:integer; //名次
sum:real; //总分
end;
var a:array[1..200] of rec; i,j,n,m,k:integer;t:rec;
begin
readln(n,m);
for i:=1 to n do
with a[i] do
begin
read(num) ;sum:=0;
for j:=1 to m do begin read(s[j]);sum:= sum+s[j] end;
m1:=0;
readln;
end;
for i:=1 to n-1 do
for j:=1 to n-i do
if (a[j].sum<a[j+1].sum)or
( a[j].sum=a[j+1].sum )and(a[j].num>a[j+1].num)
then begin t:=a[j]; a[j]:=a[j+1] ;a[j+1]:=t; end;
a[1].m1:=1;k:=1;
for i:=2 to n do
if a[i].sum=a[i-1].sum then a[i].m1:=k
else begin inc(k);a[i].m1:=k; end;
for i:=1 to n do
if i<=10 then write(a[i].num,' ')
else if a[i].sum=a[i-1].sum then write( a[i].num ,' ')
else break;
end.
2. 【布置新房】(3+3+3+3+3=15分)
笑笑今天很开心,家里购置的新房领到钥匙了,新房里有一间笑笑自己专用的很宽敞的房间。更让她高兴的是,妈妈昨天对她说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过m元钱就行”。笑笑怀里揣着m元RMB到了商场,商场里的物品真多啊,让人眼花缭乱。笑笑想买的东西很多,于是,她把想买的每件物品规定了一个重要度,用整数表示,数值越大越重要,当然每件物品都有价格,笑笑经过仔细观察,发现这个商场很奇特,所有物品的价格都是整数。笑笑希望在不超过m元(可以等于m元)的前提下,买回去布置新房的物品的重要度之和最大。
比如想买有4件物品,价格分别为3,4,5,8,对应的重要度分别为4,5,7,10,笑笑总共有12元钱,则取编号为1,2,3的物品,得到最大的重要度之和为16。
Input
第一行为m和n,中间用空格隔开,表示m元RMB和商场中有n件物品。
下面n行依次为每件物品的价格和重要度,中间用一个空格隔开。
Output
一行,表示在不超过m元的前提下笑笑购买物品的最大重要度之和。
【输入样例】
12 4
3 4
4 5
5 7
8 10
【输出样例】
16
算法思路:
穷举。用一个b数组来存放物品选取的情况,当b[i]=0时表示第i件物品不取,当b[i]=1时表示第i件物品已取,初始化全部取0,可以从后面的物品开始取起,通过b数组的取值把15种取法全部穷举出来,重要度之和max初始化为0。
b[0] b[1] b[2] b[3] b[4]
0 0 0 0 0 {初始化}
0 0 0 0 1 {取第4件物品,价格为8,不超,重要度为10,将max替换为10}
0 0 0 1 0 {取物品3,价格为5,不超,重要度为7,小于max,不换}
0 0 0 1 1 {取物品3,4,价格为13,超}
0 0 1 0 0 {取物品2,价格为4,不超,重要度为5,不换}
0 0 1 0 1
0 0 1 1 0
0 0 1 1 1
…
0 1 1 1 0{取物品1,2,3,价格为12,重要度为16,将max替换为16}
0 1 1 1 1
1 0 0 0 0{当b[0]=1时停止,b[0]称为哨兵}
program test_2012_7;
var v,p:array[1..100]of integer; //物品的价格和重要度
b:array[0..100] of 0..1; //表示物品的选取情况
i,j,m,n,max,vsum,psum:integer;
begin
readln(m,n);
for i:=1 to n do
readln(v[i],p[i]) ;
fillchar(b,sizeof(b),0);
max:=0;
while b[0]=0 do
begin
j:=n;
while b[j]=1 do dec(j);
b[j]:=1;
for i:=j+1 to n do b[i]:=0 ;
vsum:=0;psum:=0;
for j:=1 to n do
if b[j]=1 then begin vsum:=vsum+v[j] ;psum:=psum+p[j]; end;
if vsum<=m then if max<psum then max:=psum ;
end;
writeln( max );
end.