Noi-2003-木棒游戏
2012-03-16 00:17
204 查看
木棒游戏
【问题描述】
这是一个很古老的游戏。用木棒在桌上拼出一个不成立的等式,移动且只移动一根木棒使得等式成立。现在轮到你了。【任务】
从文件读入一个式子(该式子肯定是一个不成立的等式)。如果移动一根木棒可以使等式成立,则输出新的等式,否则输出No。
【说明和限制】
1.式子中的数可能是正数或负数,运算符号只会出现加号和减号,并且有且仅有一个等号,不会出现括号、乘号或除号,也不会有++,--,+-或-+出现。2.式子中不会出现8个或8个以上的连续数字(数的绝对值小于等于9999999)。
3.你只能移动用来构成数字的木棒,不能移动构成运算符(+、-、=)的木棒,所以加号、减号、等号是不会改变的。移动前后,木棒构成的数字必须严格与图2中的0~9相符。
4.从文件读入的式子中的数不会以0开头,但允许修改后等式中的数以数字0开头。
【输入数据】
从文件game.in中读入一行字符串。该串中包括一个以“#”字符结尾的式子(ASCII码35),式子中没有空格或其他分隔符。输入数据严格符合逻辑。字符串的长度小于等于1000。注意:“#”字符后面可能会有一些与题目无关的字符。
【输出数据】
将输出结果存入文件game.out,输出仅一行。如果有解,则输出正确的等式,格式与输入的格式相同(以“#”结尾,中间不能有分隔符,也不要加入多余字符)。此时输入数据保证解是唯一的。
如果无解,则输出“No”(N大写,o小写)。
【输入样例1】
1+1=3#【输出样例1】
1+1=2#【输入样例2】
1+1=3+5#【输出样例2】
No【输入样例3】
11+77=34#【输出样例3】
17+17=34#-------------------------------------------------------------------------------------------------------------------
这是一道搜索题,1000的数据规模,用平方级的算法(预处理改变量)就可以A了,但我写的是线性的,用链表优化,使搜索范围最小化,10个测试点,一次Ac,共用时0.18s,相当有成就感。
-------------------------------------------------------------------------------------------------------------------
代码:
program game; const addnum:array['0'..'9'] of longint=(1,1,0,1,0,2,1,0,0,1); addmap:array['0'..'9',1..2] of char=( {0}('8','0'), {1}('7','0'), {2}('0','0'), {3}('9','0'), {4}('0','0'), {5}('6','9'), {6}('8','0'), {7}('0','0'), {8}('0','0'), {9}('8','0') ); cutnum:array['0'..'9'] of longint=(0,0,0,0,0,0,1,1,3,2); cutmap:array['0'..'9',1..3] of char=( {0}('0','0','0'), {1}('0','0','0'), {2}('0','0','0'), {3}('0','0','0'), {4}('0','0','0'), {5}('0','0','0'), {6}('5','0','0'), {7}('1','0','0'), {8}('0','6','9'), {9}('3','5','0') ); pernum:array['0'..'9'] of longint=(2,0,1,2,0,1,2,0,0,2); permap:array['0'..'9',1..2] of char=( {0}('6','9'), {1}('0','0'), {2}('3','0'), {3}('2','5'), {4}('0','0'), {5}('3','0'), {6}('0','9'), {7}('0','0'), {8}('0','0'), {9}('0','6') ); tenk:array[0..9] of longint=( 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 ); type link=^node; node=record where:longint; ch:char; next:link; end; var addg,cutg,perg:array[-9..9,0..6] of link; s:array[1..1000] of char; N,Sum:longint; procedure scan; var ch:char; begin N:=0; while not eof do begin read(ch); inc(N); s :=ch; if ch='#' then break; end; end; procedure upload(i,flag,q:longint); var p:link; j:longint; begin //writeln('Debug:',i,#32,flag,#32,q); for j:=1 to addnum[s[i]] do begin new(p); p^.ch:=addmap[s[i],j]; p^.where:=i; p^.next:=addg[flag*(ord(addmap[s[i],j])-ord(s[i])),q]; addg[flag*(ord(addmap[s[i],j])-ord(s[i])),q]:=p; //writeln('Debug:[addg]',p^.where,#32,p^.ch,#32,flag*(ord(addmap[s[i],j])-ord(s[i])),#32,q); end; for j:=1 to cutnum[s[i]] do begin new(p); p^.ch:=cutmap[s[i],j]; p^.where:=i; p^.next:=cutg[flag*(ord(cutmap[s[i],j])-ord(s[i])),q]; cutg[flag*(ord(cutmap[s[i],j])-ord(s[i])),q]:=p; //writeln('Debug:[cutg]',p^.where,#32,p^.ch,#32,flag*(ord(cutmap[s[i],j])-ord(s[i])),#32,q); end; for j:=1 to pernum[s[i]] do begin new(p); p^.ch:=permap[s[i],j]; p^.where:=i; p^.next:=perg[flag*(ord(permap[s[i],j])-ord(s[i])),q]; perg[flag*(ord(permap[s[i],j])-ord(s[i])),q]:=p; //writeln('Debug:[perg]',p^.where,#32,p^.ch,#32,flag*(ord(permap[s[i],j])-ord(s[i])),#32,q); end; end; procedure load; var isright:boolean; flag:longint; i,j,k,temp:longint; begin flag:=1; isright:=false; i:=1; Sum:=0; while i<=N do begin 4000 if s[i]='#' then break else if s[i]='=' then begin isright:=true; flag:=-1; inc(i); end else if s[i] in ['+','-'] then begin if (s[i]='+')xor(isright) then flag:=1 else flag:=-1; inc(i); end else begin temp:=ord(s[i])-ord('0'); j:=i; while s[j+1] in ['0'..'9'] do begin inc(j); temp:=temp*10+ord(s[j])-ord('0'); end; Sum:=Sum+flag*temp; for k:=i to j do upload(k,flag,j-k); i:=j+1; end; end; //Writeln('Sum:',Sum); end; function transform(x:longint;var a,b:longint):boolean; var i,flag:longint; begin if x=0 then exit(false); if x<0 then begin flag:=-1; x:=-x; end else flag:=1; for i:=9 downto 0 do if x div tenk[i]<>0 then if x mod tenk[i]=0 then begin a:=(x div tenk[i])*flag; b:=i; //Writeln('Transform:',x,#32,a,#32,b); exit(true); end else exit(false); end; procedure ans(i,j:longint;chi,chj:char); var k:longint; begin //writeln('Ans:',i,#32,j,#32,chi,#32,chj); s[i]:=chi; s[j]:=chj; for k:=1 to N do write(s[k]); writeln; close(input); close(output); halt; end; procedure search; var i,j,a,b:longint; p:link; begin if transform(-Sum,a,b) then if perg[a,b]<>nil then ans(perg[a,b]^.where,perg[a,b]^.where,perg[a,b]^.ch,perg[a,b]^.ch); for i:=-9 to 9 do for j:=0 to 6 do while addg[i,j]<>nil do begin if transform(-i*tenk[j]-Sum,a,b) then begin //writeln(a,#32,b); p:=cutg[a,b]; while p<>nil do begin //writeln('search:',#32,i,#32,j); if p^.where<>addg[i,j]^.where then ans(p^.where,addg[i,j]^.where,p^.ch,addg[i,j]^.ch); p:=p^.next; end; end; addg[i,j]:=addg[i,j]^.next; end; end; procedure initg; var i,j:longint; begin for i:=-9 to 9 do for j:=0 to 6 do begin addg[i,j]:=nil; cutg[i,j]:=nil; perg[i,j]:=nil; end; end; procedure main; begin scan; initg; load; search; writeln('No'); end; begin assign(input,'game.in'); assign(output,'game.out'); reset(input); rewrite(output); main; close(input); close(output); end.
相关文章推荐
- Splay 维护序列 / 块状链表 NOI 2003 - 文本编辑器
- 1507: [NOI2003]Editor
- [NOI1997] 积木游戏
- [NOI2011]兔兔与蛋蛋游戏
- BZOJ1509_NOI 2003_逃学的小孩 两次遍历 树形DP
- 【搜索】【NOI2005】智慧珠游戏
- [BZOJ1501][NOI2005]智慧珠游戏
- BZOI 1507 [NOI2003] Editor
- 【BZOJ】1507: [NOI2003]Editor(Splay)
- 1509: [NOI2003]逃学的小孩
- 区间dp——[2003NOIP普及组]数字游戏
- [OpenJudge-NOI]取石子游戏
- 【费马小定理+快速幂+逆元】BZOJ3240-[NOI2013]矩阵游戏
- 块状链表(附NOI 2003 Editor,POJ 2131 Key Insertion)
- BZOJ1509: [NOI2003]逃学的小孩
- [BZOJ1507][NOI2003]Editor(块状链表)
- luogu1043【2003普及】数字游戏(区间dp)
- Office 2003: 用VSTO在Excel中写"俄罗斯方块"游戏
- NOI 2003 逃学的小孩
- [NOI 2003] Editor