试题库问题 2011-12-29
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了试题库问题 2011-12-29相关的知识,希望对你有一定的参考价值。
算法实现题8-7 试题库问题(习题 8-18)
´问题描述:
假设一个试题库中有n道试题。 每道试题都标明了所属类别。同一道题可能有多个类别
属性。现要从题库中抽取 m 道题组成试卷。并要求试卷包含指定类型的试题。试设计一个
满足要求的组卷算法。
´编程任务:
对于给定的组卷要求,计算满足要求的组卷方案。
´数据输入:
由文件input.txt提供输入数据。 文件第1行有2个正整数n和k (2 <=k<= 20, k<=n<= 1000)
k 表示题库中试题类型总数,n 表示题库中试题总数。第 2 行有 k 个正整数,第 i 个正整数
表示要选出的类型i的题数。这k个数相加就是要选出的总题数m。接下来的n行给出了题
库中每个试题的类型信息。每行的第1 个正整数p表明该题可以属于 p类,接着的 p个数是
该题所属的类型号。
´结果输出:
程序运行结束时,将组卷方案输出到文件 output.txt 中。文件第 i 行输出 “i:”后接类
型i的题号。如果有多个满足要求的方案,只要输出1 个方案。如果问题无解,则输出“No
Solution!”。
输入文件示例 输出文件示例
input.txt
3 15
3 3 4
2 1 2
1 3
1 3
1 3
1 3
3 1 2 3
2 2 3
2 1 3
1 2
1 2
2 1 2
2 1 3
2 1 2
1 1
3 1 2 3
output.txt
1: 1 6 8
2: 7 9 10
3: 2 3 4 5
——————————————
1 Program Stone; 2 var i,n,m,flow,tot,s,t,le:longint; 3 head,vh,dis,cur:array[0..2000]of longint; 4 next,date,point:array[-20000..20000]of longint; 5 procedure add(x,y,z:longint); 6 begin 7 inc(le); 8 date[le]:=z; 9 point[le]:=y; 10 next[le]:=head[x]; 11 head[x]:=le; 12 point[-le]:=x; 13 next[-le]:=head[y]; 14 head[y]:=-le; 15 end; 16 Procedure init; 17 var i,j,k,p:longint; 18 begin 19 readln(m,n); 20 s:=0;t:=n+m+1; 21 for i:=1 to m do 22 begin 23 read(j); 24 inc(tot,j); 25 add(s,i,j); 26 end; 27 for i:=1 to n do 28 begin 29 read(p); 30 for j:=1 to p do 31 begin 32 read(k); 33 add(k,i+m,1); 34 end; 35 readln; 36 add(i+m,t,1); 37 end; 38 end; 39 40 function min(a,b:longint):longint; 41 begin 42 if a<b then min:=a else min:=b; 43 end; 44 function aug(x,nf:longint):longint; 45 var i,j,l,d,minh,ins:longint; 46 begin 47 if x=t then exit(nf); 48 l:=nf; 49 i:=cur[x]; 50 while i<>0 do 51 begin 52 if (date[i]>0)and(dis[point[i]]+1=dis[x]) then 53 begin 54 cur[x]:=i; 55 d:=aug(point[i],min(l,date[i])); 56 dec(date[i],d); 57 inc(date[-i],d); 58 dec(l,d); 59 if (l=0)or(dis[s]=t+1) then exit(nf-l); 60 end; 61 i:=next[i]; 62 end; 63 if l=nf then 64 begin 65 minh:=t+1; 66 i:=head[x]; 67 while i<>0 do 68 begin 69 if (date[i]>0)and(dis[point[i]]<minh) then begin minh:=dis[point[i]];ins:=i;end; 70 i:=next[i]; 71 end; 72 cur[x]:=ins; 73 dec(vh[dis[x]]); 74 if vh[dis[x]]=0 then dis[s]:=t+1; 75 dis[x]:=minh+1; 76 inc(vh[dis[x]]); 77 end; 78 aug:=nf-l; 79 end; 80 procedure print; 81 var i,j,k:longint; 82 begin 83 for i:=1 to m do 84 begin 85 j:=head[i]; 86 write(i,‘:‘); 87 while j<>0 do 88 begin 89 if (j>0)and(date[j]=0) then write(point[j],‘ ‘); 90 j:=next[j]; 91 end; 92 writeln; 93 end; 94 end; 95 Begin 96 assign(input,‘prog87.in‘);assign(output,‘prog87.out‘); 97 reset(input);rewrite(output); 98 init; 99 vh[0]:=t+1; 100 for i:=s to t do cur[i]:=head[i]; 101 while dis[0]<t+1 do inc(flow,aug(s,maxlongint)); 102 if flow<>tot then write(‘No Soluntion!‘) 103 else print; 104 close(input);close(output); 105 end. 106 107
以上是关于试题库问题 2011-12-29的主要内容,如果未能解决你的问题,请参考以下文章
C语言必会面试题(3耶稣有13个门徒,当中有一个就是出卖耶稣的叛徒,请用排除法找出这位叛徒:13人围坐一圈,从第一个開始报号:1,2,3,1,2,3...。凡是报到“3”就退出圈子,...)(代码片段