Noip2004T4 虫食算

18 篇文章 0 订阅
14 篇文章 0 订阅

题目:

 虫食算

来源:

 Noip2004T4

题目大意:

 3个有N个字母的字符串,求使其能构成加法竖式性质的代数,并按字母顺序输出他  们

数据范围:

  N <= 26

样例:

 5

 ABCED

 BDACE

 EBBAA

1 0 3 4 2

做题思路:

 搜索是正解,从个位的每个数开始搜,而且每一步都要判断等式和这一列是否矛盾,  代码好长,当初就over在优化那里了,现在还是copy的牛代码。。仅供参考

知识点:

 搜索

var
 s:array[1..3] of string;
 a:array['A'..'Z'] of longint;
 b:array['A'..'Z'] of boolean;
 c:array[-28..50] of char;
 h:array[0..27] of char;
 n:longint;
 i,j:longint;
 tot:longint;
 ch:char;
function print:boolean;
var
 i:longint;
 ans:longint;
begin
 ans:=0;
 fori:=n downto 1 do{<当枚举完后在进行最后一步的整体判断,如若满足则输出>}
  if(a[s[1][i]]+a[s[2][i]]+ans) mod n = a[s[3][i]] thenans:=(a[s[1][i]]+a[s[2][i]]+ans) div n
 elseexit(false);
 write(a['A']);
 forch:='B' to chr(ord('A')+n-1) do write(' ',a[ch]);
 writeln;
 exit(true);
end;
function cheak:boolean;{<如果某列已经枚举了两个则计算出第三个,如果已经有三个则判断是否矛盾,如果只枚举了一个则继续,如果不矛盾则继续>}
var
 i:longint;
 bb:boolean;
begin
 fori:=n downto 1 do
  begin
   if(b[s[1][i]]) and (b[s[2][i]]) and (b[s[3][i]]) then
    if((a[s[1][i]]+a[s[2][i]]+1) mod n = a[s[3][i]]) or ((a[s[1][i]]+a[s[2][i]]) modn = a[s[3][i]]) then
    begin
     continue;
    end
   else exit(false);
   if(b[s[1][i]]) and (b[s[2][i]]) then
    if(c[(a[s[1][i]]+a[s[2][i]]) mod n] = '*') or ((c[(a[s[1][i]]+a[s[2][i]]+1) modn] = '*')) then
    begin
     continue;
    end
   else exit(false);  
   if(b[s[1][i]]) and (b[s[3][i]]) then
    if(c[a[s[3][i]]-a[s[1][i]]] = '*') or (c[a[s[3][i]]-a[s[1][i]]-1] = '*') or(c[a[s[3][i]]+n-a[s[1][i]]] = '*') or (c[a[s[3][i]]-a[s[1][i]]-1+n] = '*') then
    begin
     continue;
    end
   else exit(false);
   if(b[s[2][i]]) and (b[s[3][i]]) then
    if(c[a[s[3][i]]-a[s[2][i]]] = '*') or (c[a[s[3][i]]-a[s[2][i]]-1] = '*') or(c[a[s[3][i]]+n-a[s[2][i]]] = '*') or (c[a[s[3][i]]-a[s[2][i]]-1+n] = '*') then
    begin
     continue;
    end
   else exit(false);  
  end; 
 exit(true);
end;
procedure dfs(l:longint);
var
 i:longint;
begin
 if l> n then
  begin
   ifprint then
   begin
    halt;
    end
   elseexit;
  end;  
 fori:=n-1 downto 0 do
  ifc[i] = '*' then{<这个不是乘号,是该字母还没枚举的标志>}
  begin
   b[h[l]]:=true;
   a[h[l]]:=i;
   c[i]:=h[l];
    ifcheak then dfs(l+1);   
   b[h[l]]:=false;
   a[h[l]]:=-1;
   c[i]:='*';
   end; 
end;
begin
 for ch:='A'to 'Z' do b[ch]:=false;
 readln(n);
 readln(s[1]);
 readln(s[2]);
 readln(s[3]);
 tot:=0;
 fori:=n downto 1 do {<字母枚举顺序是字符串倒着每列自上向下>}
  forj:=1 to 3 do
   ifnot b[s[j][i]] then
   begin
    inc(tot);
    h[tot]:=s[j][i];
    b[s[j][i]]:=true;
   end;
 fori:=-28 to 50 do c[i]:='*';
 for ch:='A'to 'Z' do
  begin
  b[ch]:=false;
  a[ch]:=-1;
  end;
 dfs(1);
end.

题目来源:http://yuanti.tyvj.cn:8080/Problem_Show.asp?id=1049

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值