您的位置:首页 > 编程语言 > PHP开发

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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息