noip2011初赛试题第四大题做法

NOIP2011普及组第四题表达式的值
个人认为这题公式还比较好选的,但是写起来有点困难。。。
我最先想到的方程是:
& & f(0)=x(0)*y(0);
f(1)=x(0)*y(1)+x(1)*y(0)+x(1)*y(1);
f(0)=x(0)*y(0)+x(0)*y(1)+x(1)*y(0);
& & f(1)=x(1)*y(1);
然后 我想能不能和解决算术表达式的方法一样解决这个问题,但是后来发现好像很难用上上面的方程。
于是我放弃了解决算术表达式的方法,用了网上题解里面的方法:
首先用一个栈把算式从后往前扫一遍,找到每个反括号对应的正括号的位置,记为dis[反括号的位置]=正括号的位置。
然后到了重要的部分:
写一个函数f(l,r):(pair是[0..1]的数组)表示从l到r的一段式子的值为0、1的方案数。
在函数f中:
先从后往前找找到第一个不在括号里的+号,记下它的位置i;
如果没找到+号,再从后往前找到第一个不在括号里的*号,记下它的位置i;
如果还是没找到,说明这个式子笼罩在一个()中,那么开始找f(l+1,r-1)(排除括号)。
然后找到了i,这个l~r的式子就可以从i处分成两半(前一半(l~i-1)是x,后一半(i+1~r)是y),至此上面的方程就可以用上了,在计算f之前,先把x,y的值算出来(计算的方法同f)。
如果遇到l&r的情况,说明这一段里面已经没有符号了,那么可以放心地返回zero(zero[0]=1
zero[1]=1)了~
最后的答案输出f[0]就可以了,过程中不要忘了边算边mod10007,否则会215的哦~☆
===================================================================================================
& pair=array[0..1]
& l,i,j,kh:
& ans,zero:
& st:array[1..50000]
& dis:array[1..100000]
& ch:array[1..100000]
function f(l,r:longint):
& if l&r then
exit(zero);
& while i&=l do
& & & case
& ')':i:=dis[i];
& if i&l then
& & & while
& & case ch[i] of
& & & '*':
& & & ')':
i:=dis[i];
& & dec(i);
& if i&l then
exit(f(l+1,r-1));
& x:=f(l,i-1);
& y:=f(i+1,r);
& if ch[i]='*' then
f[0]:=(x[0]*y[0]+x[0]*y[1]+x[1]*y[0]) mod 10007;
f[1]:=(x[1]*y[1]) mod 10007;
& if ch[i]='+' then
f[0]:=x[0]*y[0] mod 10007;
f[1]:=(x[0]*y[1]+x[1]*y[0]+x[1]*y[1]) mod 10007;
& assign(input,'exp.in');reset(input);
assign(output,'exp.out');rewrite(output);
& readln(l);
& fillchar(st,sizeof(st),0);
& fillchar(ch,sizeof(ch),0);
& fillchar(dis,sizeof(dis),0);
& for i:=1 to l do read(ch[i]);
& for i:=l downto 1 do
& & & case
st[kh]:=i;
dis[st[kh]]:=i;
& zero[0]:=1;
& zero[1]:=1;
& ans:=f(1,l);
& writeln(ans[0]);
& close(input);close(output);
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。NOIP2011普及组第四题题解(附程序)_noip吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:18,215贴子:
NOIP2011普及组第四题题解(附程序)收藏
题目中所给的+和*其实就是逻辑运算符or和and,且表达式中的数字只能是0或1,这也就意味着每一步只有2种状态,分析一下可以得出一共有N(N为原式除去括号中的长度)个阶段。
但是由于两种运算符的优先程度不同,而且式子中还会存在括号,这就不符合动态规划中的最优子结构性质了。
解决办法就是用后缀表达式,转成后缀表达式之后的式子是不包含括号的,而且也是严格地从左到右结合的,符合最优子结构的性质,这样就可以应用动态规划了。
首先,一个式子中只有4种符号:+,*,(,),对于每一种符号有其对应的操作
定义一个栈(在这里可以用一个字符串代替)
+和*:先将栈顶优先级不比自己低(左括号除外)的元素弹出并输出,再进栈
(:直接进栈
):将栈顶的元素全部弹出并输出 ,直到遇见"("(左括号弹出但并不输出)
动态规划状态转移方程:设f[i]表示前I个运算符添上数字(0或1)所能得到的结果为0的方案数。设g[i]表示前I个运算符添上数字(0或1)所能得到的结果为1的方案数。则对于+号,有f[i]=f[i-1](mod 10007)
g[i]=f[i-1]*2+f[i-1](mod 10007)对于*号,则有f[i]=f[i-1]*2+g[i-1](mod 10007)
g[i]=g[i-1](mod 10007)边界为:f[0]=1
g[0]=1很明显,题目所求的就是f[N]var
f, g: array[1..100000]
function change(s: ansistring):
while ((t[length(t)] = '+') or (t[length(t)] = '*')) and (t && '') do
change := change + t[length(t)];
Delete(t, length(t), 1);
t := t + '+';
while (t[length(t)] = '*') and (t && '') do
change := change + t[length(t)];
Delete(t, length(t), 1);
t := t + '*';
//括号出栈
while t[length(t)] && '(' do
change := change + t[length(t)];
Delete(t, length(t), 1);
Delete(t, length(t), 1);
//将整个式子用一个括号括起来,处理会更加方便一些
change := '';
for i := 1 to length(s) do
case s[i] of
'(': t := t + '(';
Assign(input, 'exp.in');
Assign(output, 'exp.out');
reset(input);
rewrite(output);
readln(n);
readln(s);
t := change(s);
f[0] := 1;
g[0] := 1;
n := length(t);
for i := 1 to n do
if t[i] = '+' then
f[i] := f[i - 1] mod 10007;
g[i] := (g[i - 1] * 2 + f[i - 1]) mod 10007;
f[i] := (f[i - 1] * 2 + g[i - 1]) mod 10007;
g[i] := g[i - 1] mod 10007;
writeln(f[n]);
Close(output);end.
3D双端东方魔幻网游「大青云」勾魂公测,穿越逆转,封神故事,全新演绎!
数学方法可解答
这道题可以用分治的方法,我在考场上写了90分。
您的程序我用测试数据测只有30分
5***+*请问您输出什么?正确答案45
提高的杯具小小的探讨一下。对于*与+号能得到指定值的方法是肯定的。转为后缀后,构建一棵表达式树(参见数据结构——树)。从根节点开始,由于取得最终的0值只有可能有固定的几种方法,总方法=对于固定的方法来考虑:(左侧得需求值得方法*右侧得需求值的方法),最后求和。此法可用递归得出。这样,应该可以基本完成题目。优化方法参见递归思维非递归化。理想时间复杂度级别O(n)(注:时间复杂度没有精确计算,但是应该在2n左右,因为得到固定值的方法可以确定,最开始即可打表。求高手计算时间复杂度。)此算法应该可行,但是未实际操作。求高手实践。弱菜解答完成。
对不起,源程序是有点问题,已经改过了,晚上把AC程序发上来!
脑袋都要爆掉了……数组来构数估计要1..25000的空间链表帝,是你出场的时候了- -!
此递推貌似问题多多……
直降200!魅族 MX6售1599元起
怎么还没贴上来呢
ysf = record
f: array[1..100001]
function change(s: ansistring):
while (t[length(t)] = '+') or (t[length(t)] = '*') do
//加号入栈
change := change + t[length(t)];
Delete(t, length(t), 1);
t := t + '+';
while t[length(t)] = '*' do
//乘号入栈
change := change + t[length(t)];
Delete(t, length(t), 1);
t := t + '*';
while t[length(t)] && '(' do
//括号出栈
change := change + t[length(t)];
Delete(t, length(t), 1);
Delete(t, length(t), 1);
change := '';
for i := 1 to length(s) do
case s[i] of
'(': t := t + '(';
change := change + '_';
f[j - 1].y := (f[j - 1].y * f[j].l + f[j - 1].l * f[j].y + f[j - 1].y * f[j].y) mod 10007;
f[j - 1].l := (f[j - 1].l * f[j].l) mod 10007;
f[j - 1].l := (f[j - 1].l * f[j].y + f[j - 1].y * f[j].l + f[j - 1].l * f[j].l) mod 10007;
f[j - 1].y := (f[j - 1].y * f[j].y) mod 10007;
for i := 1 to length(t) do
if t[i] = '_' then
f[j].l := 1;
f[j].y := 1;
if t[i] = '+' then
if t[i] = '*' then
Dec(j);begin
Assign(input, 'exp.in');
Assign(output, 'exp.out');
reset(input);
rewrite(output);
readln(n);
if c && '(' then
s := s + '_' + c
//将原串加上下划线
while not eoln do
if (s[length(s)] && ')') and (c && '(') then
//判断是否加上下划线
//不能用s:=s+'_'+c,否则耗时太多,最后一个点大约要4s,也不知为啥
if s[length(s)] && ')' then
s := s + '_';
t := change(s);
//中缀转后缀
writeln(f[1].l);
Close(output);end.{与之前程序的区别就是这个程序将原串加上了下划线,因为不加下划线会影响到式子的结合顺序,如a+b*c,后缀表达式是abc*+,但如果不加下划线,程序就会将其直接转化为*+,但在求解过程中,*+是作为a*b+c来看待的,加下划线就能解决这一问题。加下划线的方法:若当前运算符是“(”或前一个运算符是“)”就不采取操作,否则就在当前运算符的前面加上下划线}
原来的程序是31,错了,你可以测一下我改过的程序,看看答案是不是对的! :)
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或NOIP2011提高组初赛试题
第十七届全国青少年信息学奥林匹克联赛初赛试题
(提高组& Pascal语言&
两小时完成)
●● 全部试题答案均要求写在答卷纸上,写在试卷纸上一律无效 ●●
一、单项选择题(共20题,每题1.5分,共计30分,每题有且仅有一个正确选项。)
1、& 在二进制下,1011001+()=1100110。
A、1011& B、1101&
C、1010& D、1111
2、字符“A”的ASCII码为十六进制41,则字符“Z”的ASCII码为十六进制的()。
&&&D、视具体的计算机而定
3、右图是一棵二叉树,它的先序遍历是( )。
A、ABDEFC&&
B、DBEFAC&&
C、DFEBCA&& D、ABCDEF
4、寄存器是( )的重要组成部分。
A、硬盘&&&
B、高速缓存&&&
C、内存&&&
D、中央处理器(CPU)
5、广度优先搜索时,需要用到的数据结构是( )
A.链表&&&&&&&&&&
B.队列&&&&&&&&&&&&&
C.栈&&&&&&&&&&&&&&
D.散列表&
6.在使用高级语言编写程序时,一般提到的“空间复杂度”中的空间是指(&&&
A.程序运行时理论上所占的内存空间&&&
B.程序运行时理论上所占的数组空间
C.程序运行时理论上所占的硬盘空间&&&
D.程序源文件理论上所占的硬盘空间
7.应用快速排序的分治思想,可以实现一个求第K大数的程序。假定不考虑极端的最坏情况,理论上可以实现的最低的算法时间复杂度为(&&&&
(n2)&&&&&&&&&&
B.O (n log n
)&&&&&&&&&
(n)&&&&&&&&
8.为解决web应用中的不兼容问题,保障信息的顺利流通,(&&&&
)制定了一系列标准,涉及HTML、XML、CSS等,并建议开发者遵循。
B.美国计算机协会(ACM)&&
C.联合国教科文组织&& D.万维网联盟(W3C)
9.体育课的铃声响了,同学们都陆续的奔向操场,按老师的要求从高到低站成一排。每个同学按顺序来到操场时,都从排尾走到排头,找到第一个比自己高的同学,并站在他的后面。这种站队的方法类似于(&
A.快速排序&&&&&&&&&
B.插入排序&&&&&&&&&
C.冒泡排序&&&&&&&&&
D.归并排序
10.1956年(& )授予肖克利(William Shockley)、巴丁(John
Bardeen)和布拉顿(Walter Brattain)
A.诺贝尔物理学奖&&&&&&
B.约翰&冯&诺依曼奖&&
C.图灵奖&&&&&&&&&&&&&&
D.高德纳奖 (Donald E. Knuth Prize)
二、不定项选择题(共10题,每题1.5分,共计15分。每题正确答案的个数不少于1。多选或少选均不得分)。
1.如果根结点的深度记为1,则一棵恰有2011个叶子结点的二叉树的深度可能是(& )。
A.10&&&&&&&&&&
&&B.11&&&&&&&&&&&&
C.12&&&&&&&&&&&&&
2.在布尔逻辑中,逻辑“或”的性质有(&& )。
&& A.交换律:PVQ =
&&B.结合律:PV(QVR)=(PVQ)VR
&& C.幂等律:PVP =
&&&&&D.有界律:PV1
= 1(1表示逻辑真)
3.一个正整数在十六进制下有100位,则它在二进制下可能有(& )位。
A.399&&&&&&&&&&&
B.400&&&&&&&&&&&
C.401&&&&&&&&&&&
4.汇编语言(&&&
&& A.是一种与具体硬件无关的程序设计语言
B.在编写复杂程序时,相对于高级语言而言代码量大,且不易调试
&& C.可以直接访问寄存器、内存单元、I/O端口
D.随着高级语言的诞生,如今已被完全淘汰,不再使用
5.现有一段文言文,要通过二进制哈夫曼编码进行压缩。简单起见,假设这段文言文只由4个汉字“之”、“乎”、“者”、“也”组成,它们出现的次数分别为700、600、300、400。那么,“也”字的编码长度可能是(&
A.1&&&&&&&&&&&&
B.2&&&&&&&&&&&
C.3&&&&&&&&&&&&
6.生物特征识别,是利用人体本身的生物特征进行身份认证的一种技术。目前,指纹识别、虹膜识别、人脸识别等技术已广泛应用于政府、银行、安全防卫等领域。以下属于生物特征识别技术及其应用的是(&
A.指静脉验证&&&&&&
B.步态验证&&&&&&&&
C.ATM机密码验证&&&
D.声音验证
7.对于序列“7、5、1、9、3、6、8、4”,在不改变顺序的情况下,去掉(&&
)会使逆序对的个数减少3。
A.7&&&&&&&&&&&&&
B.5&&&&&&&&&&&&&
C.3&&&&&&&&&&&&
8.计算机中的数值信息分为整数和实数(浮点数)。实数之所以能够表示很大或者很小的数,是由于使用了(&&&
A.阶码&&&&&&&&&
B.补码&&&&&&&&&&
C.反码&&&&&&&&
D.较长的尾数
9.对右图使用Dijkstra算法计算S点到其余各点的最短路径长度时,到B点的距离d[B]初始时赋为8,在算法的执行过程中还会出现的值有(&&&
A.3&&&&&&&&&&&&&
7&&&&&&&&&&&&&
C.6&&&&&&&&&
10.为计算机网络中进行数据交换而建立的规则、标准或约定的集合称为网络协议。下列英文缩写中,(&&
)是网络协议
A.HTTP&&&&&&&&&&&&&&
B.TCP/IP&&&&&&&&&&&
C.FTP&&&&&&&&&&&&
三.问题求解(共2题,每空5分,共计10分)
1.平面图可以在画在平面上,且它的边仅在顶点上才能相交的简单无向图。4个顶点的平面图至少有6条边,如右图所示。那么,5个顶点的平面图至少有________条边。
2.定义一种字符串操作,一次可以将其中一个元素移到任意位置。举例说明,对于字符串“BCA”可以将A移到B之前,变字符串“ABC”。如果要将字符串“DACHEBGIF”变成“ABCDEFGHI”最少需要________次操作。
四.阅读程序写结果(共4题,每题8分,共计32分)
Const size=100;
Var n,i,sum,x: a:array[1..size]
&Readln(n); fillchar(a,sizeof(a),0);
&For i:=1 to n do
&& Read(x); inc(a[x]);
i:=0; sum:=0;
while sum&(n div 2 + 1) do
inc(i); sum:=sum+a[i];
writeln(i);
4 5 6 6 4 3 3 2 3 2 1
输出:__________&&&&&&
procedure f2(x,y:integer);
procedure f1(x,y:integer);
procedure f2(x,y:integer);
write(x,’ ’);& f1(y,x+y);
readln(n);
输出:__________
Const &v = 100;
visited:array[1..v]
e:array[1..v,1..v]
n,m,ans,i,j,a,b,c:
procedure dfs(x,len:integer);
visited[x] :=
if len & ans then& ans:=
for i:=1 to n do
if (not visited(i)) and(e[x,i] && -1)
dfs(I,len+e[x,i]);
visited[x] :=
readln(n,m);
for i:=1 to n do
&& for j:=1 to n do
e[i][j] := -1;
for i:=1 to m do
readln(a,b,c); &e[a][b]:=c;
&e[b][a]:=c;
for i:=1 to n do& visited[i]:=
for i:=1 to n do& dfs(i,0);
writeln(ans);
输出:______
Const SIZE = 10000; &LENGTH = 10;
var& sum :
&n,m,I,j :
a:array[1..SIZE , 1..LENGTH]
function h(u , v :integer):
var ans,i :
for i:=1 to n do
&& if a[u][i]
&& a[v][i] then&
readln(n);& &fillchar(a,sizeof
(a),0); &m:=1;
while (i &=n) and (a[m][i] =1 ) do&
if i&n then&
inc(m); &a[m][i]:=1;
for j:=i + 1 to n do& a[m][j] := a[m-1][j];
for i := 1 to m do
&& for j := 1 to m do
sum := sum + h(i,j);
writeln(sum);
输出:______
五.完善程序 (第1题,每空2分,第2题,每空3分,共28分)
1.(大整数开方)&
输入一个正整数n(1≤n≤10100),试用二分法计算它的平方根的整数部分。
Const size=200;
Type hugeint=record
&&Num:array[1..size] of
//len表示大整数的位数;num[1]表示个位、num[2]表示十位,以此类推
Target,left,middle,right:
Function times(a,b:hugeint):
Var i,j: ans:
&Fillchar(ans,sizeof(ans),0);
&For i:=1 to a.len do
&& For j:=1 to b.len do
①&&&&
:=ans.num[i + j - 1] + a.num[i] * b.num[j];
for i:=1 to a.len+b.len do
&& ans.num[i + 1] := ans.num[i
+ 1] + ans.num[i] div 10;
②&&; &
if ans.num[a.len + b.len] & 0
then ans.len := a.len + b.len
else ans.len := a.len + b.len - 1;
function add(a,b : hugeint) :
fillchar(ans.num,sizeof(ans.num),0);
if a.len&b.len& then ans.len :=
&else ans.len := b.
for i := 1 to ans.len do
&ans.num[i]:= ③ ;
&ans.num[i+1] := ans.num[i+1] + ans.num[i] div
&ans.num[i] := ans.num[i] mod 10;
if ans.num[ans.len + 1]&0 &then
&inc(ans.len);
function average(a,b: hugeint) :
var &i : ans :
ans := add(a,b);
for i:= ans.len downto 2 do
&ans.num[i-1] := ans.num[i-1] + ( ④ ) *10;
&ans.num[i]:=ans.num[i] div 2;
ans.num[1]:=ans.num[1] div 2;
if ans.num[ans.len] = 0 &then dec(ans.len);
average :=
function plustwo(a : hugeint) :
&ans.num[1] := ans.num[1] + 2;
&while (i &= ans.len) and
(ans.num[i] &= 10) do
&ans.num[i + 1] := ans.num[i + 1] + ans.num[i] div
&ans.num[i] := ans.num[i] mod 10;
&if ans.num[ans.len + 1] &
0& &then ⑤;
&plustwo :=
function over(a , b: hugeint) :
if ( ⑥ ) then
if a.len & b.len then
for i := a.len downto 1 do
if a.num[i] & b.num[i] then
if a.num[i] & b.num[i] then
readln(s);
&&fillchar(target.num,sizeof(target.num),0);
target.len := length(s);
for i := 1 to target.len do
target.num[i] := ord(s[target.len - i +1]) - &⑦
fillchar(left.num,sizeof(left,num),0);
left.len:=1; &&left.num[1]:=1;
middle:=average(left,right);
if over( ⑧ )&& then right :=
&&&&&&&&&else
until over(plustwo(left),right);
for i:= left.len downto 1 do
write(left.num[i]);
(笛卡尔树)对于一个给定的两两不等的正整数序列,笛卡尔树是这样的一棵二叉树:首先,它是一个最小堆,即除了根结点,每个节点的权值都大雨父节点的权值;其次,它的中序遍历恰好就是给定的序列。例如,对于序列7、2、12、1、10、5、15、3,下图就是一棵对应的笛卡尔树。现输入序列的规模n(1≤n&100)和序列的n个元素,试求其对应的笛卡尔树的深度d(根节点深度为1),以及有多少个叶子节点的深度为d。
SIZE = 100;
INFINITY = 1000000;
n , maxDeep, num , i :
a : array[1..SIZE]
procedure solve(left , right , deep : integer);
if deep&maxDeep then
maxDeep :=
else if deep=maxDeep then
min := INFINITY;
for i := left to right do
if min & a[i] then
min := a[i];
if left & j then
readln(n);
for i := 1 to n do
read(a[i]);
maxDeep:=0;
solve( 1, n, 1);
writeln(maxDeep, ‘ ‘, num);
NOIP2011年提高组(Pascal)参考答案与评分标准
一、单项选择题:(每题1.5分)
二、 不定项选择题(共10题,每题1.5分,共计15分。每题正确答案的个数大于或等于1。多选或少选均不得分)。
ABCD&&&&&&&&
6. ABD&&& 7.
三、问题求解:(共2题,每空5分,共计10分)
四、阅读程序写结果(共4题,每题8分,共计32分)
&2.1 2 5 13 34
五、完善程序(第1题,每空2分,第2题,每空3分,共计28分)
(说明:以下各程序填空可能还有一些等价的写法,各省可请本省专家审定和上机验证,不一定上报科学委员会审查)
① ans.num[i+j-1]
② ans.num[i]:=ans.num[i] mod 10
③ ans.num[i]+a.num[i]+b.num[i]
④ ans.num[i] mod 2
⑤ inc(ans.len)
⑥ a.len⑦ ord(‘0’)或48
⑧ times(middle,middle),target
① inc(num)
② j:=i
③ solve(left,j-1,deep+1)
④ solve(j+1,right,deep+1)
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。NOIP2011第一天第三题怎么做?
冷死piPB54OF18
比较复杂的搜索题……剪枝方案:(1)\x05每次搜索只搜到最高层即可,不用全部搜索……(2)\x05当左右两个点相同时,移动和不移动是一样的,则我们不用移动……(3)\x05搜索每一个点,我们会发现将F[i,j]向右移和将F[i+1,j]向左移是一样的,则我们只搜索向右移的……注意要把数组开大些,防止移动时出错(我一开始开到5*7的数组,总是有几个点过不去,郁闷了好长时间……),转移状态时不要出错……type tyy=array[0..10,0..10]var f:n,i,a,b:x,y,z:array[0..10]function jiancha(ff:tyy): //检查最低层是否都消去var i,j:beginfor i:=0 to 4 doif ff[i,0]0 then exit(false);exit(true)var i:beginfor i:=1 to n dowriteln(x[i],' ',y[i],' ',z[i]);close(input); close(output); //若有多种方案则以x为第一关键字按字典序输出,因为搜索时按x从0到4搜索的,故找到第一种方案是可以直接退出程序procedure dfs(k: ff:tyy);procedure check(k: ff:tyy);var bt:array[0..4,0..7]boo:i,j,kk,t:beginboo:=while (not boo) do //判断是否能下降,若没有下降则说明没有能消除的方块beginfor i:=0 to 4 do for j:=0 to 7 do bt[i,j]:= //初始化bt,记录能否消除for i:=0 to 4 do for j:=0 to 7 do //消除三个连续相同的beginif ff[i,j]=0if (ff[i,j]=ff[i,j+1])and(ff[i,j+1]=ff[i,j+2])and(ff[i,j]0)thenbeginbt[i,j]:=bt[i,j+1]:=bt[i,j+2]:=if (ff[i,j]=ff[i+1,j])and(ff[i+1,j]=ff[i+2,j])and(ff[i,j]0)thenbeginbt[i,j]:=bt[i+1,j]:=bt[i+2,j]:=for i:=0 to 4 do for j:=0 to 7 do if bt[i,j] then ff[i,j]:=0;boo:=for i:=0 to 4 do //下降for j:=0 to 7 doif ff[i,j]=0 thenbegint:=j;while (t7for kk:=0 to t-j do beginff[i,j+kk]:=ff[i,t+kk];ff[i,t+kk]:=0;boo:=if (kn+1)and(jiancha(ff)) //若不是在规定步数走完,则退出if (k=n+1)and(jiancha(ff)) //若恰好在规定步数消完,则输出dfs(k,ff);procedure dfs(k: ff:tyy);var i,j,tt:beginif k>for j:=0 to 4 dofor i:=0 to 7 dobeginif (ff[j,i]=0)if (ff[j-1,i]=0)and(j0)and(ff[j,i]ff[j-1,i]) then //若可以交换,则尝试交换beginx[k]:=j; y[k]:=i; z[k]:=-1;tt:=ff[j,i]; ff[j,i]:=ff[j-1,i]; ff[j-1,i]:=check(k+1,ff);tt:=ff[j,i]; ff[j,i]:=ff[j-1,i]; ff[j-1,i]:=x[k]:=0; y[k]:=0; z[k]:=0;if j=4 //若搜索到最后一列,则不能向右移动,退出本次循环if ff[j,i]=ff[j+1,i]x[k]:=j; y[k]:=i; z[k]:=1;tt:=ff[j,i]; ff[j,i]:=ff[j+1,i]; ff[j+1,i]:=check(k+1,ff);tt:=ff[j,i]; ff[j,i]:=ff[j+1,i]; ff[j+1,i]:=x[k]:=0; y[k]:=0; z[k]:=0;beginassign(input,'mayan.in');reset(input);assign(output,'mayan.out');rewrite(output);readln(n);for i:=0 to 4 do //读入数据beginb:=-1;repeatread(a);inc(b);f[i,b]:=a;until a=0;x[0]:=-1; y[0]:=-1; z[0]:=-2; //将x、y、z数组初始化dfs(1,f);writeln('-1'); //若没有解决方案,输出-1close(input); close(output);end.自我感觉程序比较慢,各位大神应该还有更好的方法,希望能交流一下,欢迎鄙视……
为您推荐:
其他类似问题
扫描下载二维码君,已阅读到文档的结尾了呢~~
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
Noip2011普及组Pascal初赛题及参考答案
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口

我要回帖

更多关于 noip2011初赛试题 的文章

 

随机推荐