Noi-2003-木棒游戏

来源:互联网 发布:重庆文理学院教务网络 编辑:程序博客网 时间:2024/05/01 21:12

木棒游戏

【问题描述】

这是一个很古老的游戏。用木棒在桌上拼出一个不成立的等式,移动且只移动一根木棒使得等式成立。现在轮到你了。

【任务】

从文件读入一个式子(该式子肯定是一个不成立的等式)。

如果移动一根木棒可以使等式成立,则输出新的等式,否则输出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[N]:=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           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.