考试时间:8:30-12:00,时限:1秒,内存:256M
试题一、达尔文芯片问题(本题满分100分)
源程序:cores.c/cores.cpp/cores.pas/cores.pp
«问题描述:
人的大脑里发生的一切是神奇的,甚至是不可理解的,正是这种神奇使得人具有自我意识。如果用普通硅片、电路、传感器制成的机器人也能进化,从而能有意识的行动,那么是否有一天,机器人也会变得和人一样有意识?电脑的硬件也许能像自然界人类和其他生物进化的方式进行进化这一想法,早在上世纪60年代就被提出,但如何着手是到1998年,因美籍华裔计算机科学家的一个灵感,才得以突破。这一灵感就是被称为达尔文芯片的高集成度可编程集成电路块,简称为DPGA。
最近,福州大学计算机学院计算机神经学研究小组的科学家们发现,对达尔文芯片的关键逻辑元进行重组后产生一种奇特的现象。将若干关键逻辑元按照电路板平面坐标系2维降序排列,经过电路演化,这些关键逻辑元自动按照x坐标和y坐标方向联接成一棵树。这棵树的每条边都平行于x坐标轴或平行于y坐标轴。关键逻辑元构成这棵树的全部叶结点。这类树称为以关键逻辑元为叶结点的正交树。有趣的是,达尔文芯片自动产生的正交树的总边长是所有这种正交树中总边长最小的。例如,将5个关键逻辑元分别置于电路板xoy坐标系中(1,5),(2,4),(3,3),(4,2)和(5,1)处,则达尔文芯片自动产生的一棵正交树如下图所示,它的总边长为12。
«编程任务:
给定电路板xoy坐标系,以及电路板上n个关键逻辑元在xoy坐标系中按照2维降序排列的位置,,…,。其中,;
; 。
编程计算以这n个关键逻辑元为叶结点的正交树中,总边长最小的最优正交树总边长的值。
«数据输入:
输入数据由文件名为INPUT2.*的文本文件提供。
n 第1行中的整数为关键逻辑元个数n;
n 接下来的n行中每行一个整数,依次为;
n 最后的n行中每行一个整数,依次为。
«结果输出:
程序运行结束时,在屏幕上输出所找到的最优正交树总边长的值。
输入文件示例 |
输出示例 |
INPUT2.001 |
12 |
5 1 2 3 4 5 5 4 3 2 1 |
|
试题二、车皮编序问题(本题满分100分)
源程序:stack.c/stack.cpp/stack.pas/stack.pp
«问题描述:
在一个列车调度站中,2条轨道连接到2条侧轨处,形成2个铁路转轨栈。其中左边轨道为车皮入口,编号为A;右边轨道为出口,编号为D,2个铁路转轨栈分别编号为B和C,如下图所示。编号为a,b,…,的n个车皮依序停放在车皮入口处。调度室要安排各车皮进出栈次序,使得在出口处各车皮按照预先指定的顺序依次出站。车皮移动时只能按照从左到右的方向移动。
«编程任务:
给定车皮数0<n<=21,以及各车皮的出站顺序,编程计算最优调度方案,使得移动车皮的总次数最少。
«数据输入:
由文件input.txt给出输入数据。第一行有1个正整数n,表示车皮数。接下来的1行中,是预先指定的车皮出站顺序。
«结果输出:
将计算的最优调度方案输出到文件output.txt。文件的第一行是最少移动次数m。接下来的m行是对应于最优方案的m次移动。每次移动用形如‘cX Y’的3个字符来表示,其中c表示车皮编号,X表示起始栈轨号,Y表示目标栈轨号。如果有多个最优方案,输出任意一种即可。如果无法调度则输出“No Solution!”。
输入文件示例 |
输出文件示例 |
input.txt |
output.txt |
3 abc |
5 c A B b A B a A D b B D c B D |
【思路】搜索+剪枝 下面代码是不输出方案的
var b,c:array[1..30]of char; p:array[1..30]of integer; min,n,i:integer; des:string; procedure search(topa,topb,topc,topd,m:integer); var ch:char; begin if topd=n then begin if m<min then min:=m; exit; end; if topa+topb+topc+m>=min then exit; //直接出栈 if (topa>0)and(96+topa=ord(des[topd+1])) then begin search(topa-1,topb,topc,topd+1,m+1); exit; end; if (topb>0)and(b[topb]=des[topd+1]) then begin ch:=b[topb]; // search(topa,topb-1,topc,topd+1,m+1); b[topb]:=ch; exit; end; if (topc>0)and(c[topc]=des[topd+1]) then begin ch:=c[topc]; search(topa,topb,topc-1,topd+1,m+1); c[topc]:=ch; exit; end; //a->c if topa>0 then begin if (topc=0)or(p[topa]<p[ord(c[topc])-96]) then begin c[topc+1]:=chr(topa+96); search(topa-1,topb,topc+1,topd,m+1); c[topc+1]:=' '; end; //a->b b[topb+1]:=chr(topa+96); search(topa-1,topb+1,topc,topd,m+1); b[topb+1]:=' '; end; if topb>0 then begin if (topc=0)or(p[ord(b[topb])-96]<p[ord(c[topc])-96]) then begin ch:=b[topb]; c[topc+1]:=b[topb]; b[topb]:=' '; search(topa,topb-1,topc+1,topd,m+1); b[topb]:=ch; c[topc+1]:=' '; end else exit; end; end; begin assign(input,'input.txt'); reset(input); assign(output,'output.txt'); rewrite(output); readln(n); readln(des); for i:=1 to length(des) do p[ord(des[i])-96]:=i; min:=maxint; search(n,0,0,0,0); if min=maxint then writeln('No Solution!') else writeln(min); close(input); close(output); end.
试题三、半数集问题(本题满分100分)
源程序:set.c/set.cpp/set.pas/set.pp
«问题描述:
给定一个自然数n,由n开始可以依次产生半数集set(n)中的数如下。
(1) n∈set(n);
(2) 在n的左边加上一个自然数,但该自然数不能超过最近添加的数的一半;
(3) 按此规则进行处理,直到不能再添加自然数为止。
例如,set(6)={6,16,26,126,36,136}。半数集set(6)中有6个元素。
注意半数集不是多重集。集合中已经有的元素不再添加到集合中。
«编程任务:
对于给定的自然数n,编程计算半数集set(n)中的元素个数。
«数据输入:
输入数据由文件名为input.txt的文本文件提供。
每个文件只有1行,给出整数n。(0<n<201)
«结果输出:
程序运行结束时,将计算结果输出到文件output.txt中。输出文件只有1行,给出半数集set(n)中的元素个数。
输入文件示例 |
输出文件示例 |
input.txt |
output.txt |
6 |
6 |
【思路】http://www.docin.com/p-308779519.html
#include <cstdio> #include <cstring> int a[201]; int work(int n) { int ans=1; if(a[n]>0) return a[n]; for(int i=1;i<=n/2;i++) { ans+=work(i); if((i>10)&&(i/10<=(i%10)/2)) ans-=a[i/10]; } return a[n]=ans; } int main() { int n; freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); scanf("%d",&n); printf("%d",work(n)); }