USACO 2.3 和为零 (DFS)

Description

  请考虑一个由1到N(N=3, 4, 5 … 9)的数字组成的递增数列:1 2 3 … N。
  现在请在数列中插入“+”表示加,或者“-”表示减,抑或是“ ”表示空白,来将每一对数字组合在一起(请不在第一个数字前插入符号)。
  计算该表达式的结果并注意你是否得到了和为零。
  请你写一个程序找出所有产生和为零的长度为N的数列。

Input

  单独的一行表示整数N (3 <= N <= 9)。

Output

  按照ASCII码的顺序,输出所有在每对数字间插入“+”, “-”, 或 “ ”后能得到和为零的数列。(注意:就算两个数字之间没有插入符号也应该保留空格)

题解

dfs;
Executing...
   Test 1: TEST OK [0.000 secs, 340 KB]
   Test 2: TEST OK [0.000 secs, 340 KB]
   Test 3: TEST OK [0.000 secs, 340 KB]
   Test 4: TEST OK [0.000 secs, 340 KB]
   Test 5: TEST OK [0.000 secs, 340 KB]
   Test 6: TEST OK [0.000 secs, 340 KB]
   Test 7: TEST OK [0.022 secs, 340 KB]
All tests OK.

代码

{
ID: zyx52yzl
LANG: PASCAL
TASK: zerosum
}
var
  a,b,c:array [0..101] of longint;
  i,j,n:longint;
function main:boolean;
var
  i,j,ii:longint;
begin
  for i:=1 to n-1 do
    for j:=1 to n-1 do
      if b[j]=100 then
        begin
          a[j]:=a[j]*10+a[j+1];
          for ii:=j to n do
            begin
              a[ii+1]:=a[ii+2];
              b[ii]:=b[ii+1];
            end;
          break;
        end;
  for i:=1 to n-1 do
    for j:=1 to n-1 do
      begin
        if b[j]=101 then a[j]:=a[j]-a[j+1]
                    else if b[j]=102 then a[j]:=a[j]+a[j+1];
        for ii:=j to n do
          begin
            a[ii+1]:=a[ii+2];
            b[ii]:=b[ii+1];
          end;
        if (b[j]=101) or (b[j]=102) then break;
      end;
  if a[1]=0 then main:=true
            else main:=false;
end;

procedure print;
var
  i:longint;
begin
  for i:=1 to n-1 do
    begin
      write(i);
      if b[i]=100 then write(' ')
        else if b[i]=101 then write('-')
          else write('+');
    end;
  writeln(n);
end;

procedure dfs(dep:longint);
var
 i,j:longint;
begin
  if dep=n then
    begin
      c:=b;
      if  main then
        begin
          for i:=1 to n do
            a[i]:=i;
          b:=c;
          print;
        end;
      for i:=1 to n do
        a[i]:=i;
      b:=c;
      exit;
    end;
  b[dep]:=100;
  dfs(dep+1);
  b[dep]:=102;
  dfs(dep+1);
  b[dep]:=101;
  dfs(dep+1);
end;

begin
  assign(input,'zerosum.in');
  assign(output,'zerosum.out');
  reset(input);
  rewrite(output);
  readln(n);
  for i:=1 to n do
    a[i]:=i;
  dfs(1);
  close(input);
  close(output);
end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值