USCAO section 2.3 Zero Sum(dfs)

Zero Sum

Consider the sequence of digits from 1 through N (where N=9) in increasing order: 1 2 3 ... N.

Now insert either a `+' for addition or a `-' for subtraction or a ` ' [blank] to run the digits together between each pair of digits (not in front of the first digit). Calculate the result that of the expression and see if you get zero.

Write a program that will find all sequences of length N that produce a zero sum.

PROGRAM NAME: zerosum

INPUT FORMAT

A single line with the integer N (3 <= N <= 9).

SAMPLE INPUT (file zerosum.in)

7

OUTPUT FORMAT

In ASCII order, show each sequence that can create 0 sum with a `+', `-', or ` ' between each pair of numbers.

SAMPLE OUTPUT (file zerosum.out)

1+2-3+4-5-6+7
1+2-3-4+5+6-7
1-2 3+4+5+6+7
1-2 3-4 5+6 7
1-2+3+4-5+6-7
1-2-3-4-5+6+7


 

解题思路:直接深搜三种状态,最多3^8不超,注意点细节就OK了,纯水

 

/*
ID:nealgav1
PROG:zerosum
LANG:C++
*/
#include<fstream>
#include<cstring>
using namespace std;
const int mm=10000;
char s[mm][25],num;
char _s[25];
ifstream cin("zerosum.in");
ofstream cout("zerosum.out");
void dfs(char now,int x,int end,int sum,char pas)
{
  _s[2*x-3]=now;_s[2*x-2]=x+'0';
  if(now==' '&&pas=='+')
  {sum+=(x-1)*9+x;
   if(x==end)
   { _s[2*x-3]=now;_s[2*x-2]=x+'0';
     _s[0]='0'+1;
    _s[2*x-1]='\0';
    if(sum==0)cout<<_s<<"\n";
    return;
   }
  dfs(' ',x+1,end,sum,now);
  dfs('+',x+1,end,sum,now);
  dfs('-',x+1,end,sum,now);
  }
  else if(now==' '&&pas=='-')
  {
    sum=sum-x-(x-1)*9;
    if(x==end)
   { _s[2*x-3]=now;_s[2*x-2]=x+'0';
     _s[0]='0'+1;
    _s[2*x-1]='\0';
    if(sum==0)cout<<_s<<"\n";
    return;
   }
  dfs(' ',x+1,end,sum,now);
  dfs('+',x+1,end,sum,now);
  dfs('-',x+1,end,sum,now);
  }
  if(now=='+')
  {
    sum+=x;
    if(x==end)
    { _s[2*x-3]=now;_s[2*x-2]=x+'0';
      _s[0]='0'+1;
    _s[2*x-1]='\0';
    if(sum==0)cout<<_s<<"\n";
    return;
    }
  dfs(' ',x+1,end,sum,now);
  dfs('+',x+1,end,sum,now);
  dfs('-',x+1,end,sum,now);
  }
  if(now=='-')
  {sum-=x;
   if(x==end)
   { _s[2*x-3]=now;_s[2*x-2]=x+'0';
     _s[0]='0'+1;
    _s[2*x-1]='\0';
    if(sum==0)cout<<_s<<"\n";
    return;
   }
  dfs(' ',x+1,end,sum,now);
  dfs('+',x+1,end,sum,now);
  dfs('-',x+1,end,sum,now);
  }
}
int main()
{

  int m;
  cin>>m;
  num=0;
  dfs(' ',2,m,1,'+');
  dfs('+',2,m,1,'+');
  dfs('-',2,m,1,'+');
}


 

 

 

 

 

 

USER: Neal Gavin Gavin [nealgav1]
TASK: zerosum
LANG: C++

Compiling...
Compile: OK

Executing...
   Test 1: TEST OK [0.000 secs, 3580 KB]
   Test 2: TEST OK [0.000 secs, 3580 KB]
   Test 3: TEST OK [0.000 secs, 3580 KB]
   Test 4: TEST OK [0.000 secs, 3580 KB]
   Test 5: TEST OK [0.000 secs, 3580 KB]
   Test 6: TEST OK [0.000 secs, 3580 KB]
   Test 7: TEST OK [0.000 secs, 3580 KB]

All tests OK.

YOUR PROGRAM ('zerosum') WORKED FIRST TIME! That's fantastic -- and a rare thing. Please accept these special automated congratulations.

Here are the test data inputs:

------- test 1 ----
3
------- test 2 ----
4
------- test 3 ----
5
------- test 4 ----
6
------- test 5 ----
7
------- test 6 ----
8
------- test 7 ----
9
Keep up the good work!


Thanks for your submission!

 

Zero SumRuss Cox

We can use a simple recursive depth first search to generate all the possible strings to be had by putting in a space, plus, or minus sign between each number.

Once we've generated each string, we evaluate it as an arithmetic sum and see if we get zero. If so, we print the string.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

FILE *fout;
int n;

/* evaluate the string s as arithmetic and return the sum */
int
eval(char *s)
{
    int term, sign, sum;
    char *p;

    sign = 1;
    term = 0;
    sum = 0;
    for(p=s; *p; p++) {
        switch(*p){
        case '+':
        case '-':
            sum += sign*term;
            term = 0;
            sign = *p == '+' ? 1 : -1;
            break;
        case ' ':
            break;
        default:    /* digit */
            term = term*10 + *p-'0';
        }
    }
    sum += sign*term;
    return sum;
}

/* 
 * Insert + - or space after each number, and then  
 * test to see if we get zero.  The first k numbers have
 * already been taken care of.
 */
void
search(char *s, int k)
{
    char *p;

    if(k == n-1) {
        if(eval(s) == 0)
            fprintf(fout, "%s\n", s);
        return;
    }

    for(p=" +-"; *p; p++) {
        s[2*k+1] = *p;
        search(s, k+1);
    }
}


void
main(void)
{
    FILE *fin;
    int i;
    char str[30];

    fin = fopen("zerosum.in", "r");
    fout = fopen("zerosum.out", "w");
    assert(fin != NULL && fout != NULL);

    fscanf(fin, "%d", &n);

    strcpy(str, "1 2 3 4 5 6 7 8 9");
    str[2*n-1] = '\0';    /* chop string to only have first n numbers */

    search(str, 0);

    exit(0);
}


 

posted @ 2012-09-08 20:48  剑不飞  阅读(216)  评论(0编辑  收藏  举报