DFS+uva10317

来源:互联网 发布:一骑当千镜头数据 编辑:程序博客网 时间:2024/05/01 23:57

Problem F

Equating Equations

Input: standardinput

Output: standardoutput

Time Limit: 6 seconds

Memory Limit: 32MB

 

Read equations with up to 16 terms and + and operators (not unary) and reorder theterms (but not the operators) so that the equations hold. For example

 
   1 + 2 = 4 - 5 + 6

isnot a correct equation but the terms can be rearranged thus so it is:

 
   6 + 2 = 4 - 1 + 5

Input

Standardinput consists of several pseudo-equations, one per line. Each pseudo-equationhas up to16 integer terms and eachterm is less than 100. Adjacentterms are separated by one operator, and spaces always appear surrounding theterms. There is exactly one = operator in the equation

Output

Youroutput will consist of one line per input line, with the same operators and thesame terms. The order of the operators must be preserved, but the terms can bereordered so the equation holds. Any ordering such that the equation holds iscorrect. If there is more than one ordering any one of the orderings will do.If no ordering exists, a line containing

   no solution

should beprinted. One space should appear on either side of each operator and thereshould be no other spaces.

Sample Input

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

Sample Output

6 + 2 = 4 - 1 + 5
no solution


蛋疼的模拟题。。

先把等式的右面移向,然后相当于让正数的和等于负数的和,2^16次方枚举,可以状态压缩,也可以dfs

#include<cstdio>#include<cstring>using namespace std;const int maxn = 1000;char str[10000];char sigma[maxn];bool vis[maxn];int  num[maxn], ans[maxn], n, idx;int  plus[maxn], leftNum, plusNum, sum;void read(){    idx = 1;    sscanf(str, "%d", &num[0]);    sum = num[0];    int len = strlen(str);    for(int i=1; i<len; ++i){        if(str[i]=='+' || str[i]=='-' || str[i]=='=') {            if(str[i] == '=')                leftNum = idx;            sigma[idx] = str[i];            sscanf(str+i+1, "%d", &num[idx]);            sum += num[idx++];        }    }    // 把等式全部移到左边后,计算有多少个加号    plusNum = 1;    for(int i=1; i<idx; ++i){        if(i<leftNum && sigma[i] == '+'){            ++plusNum;        } else if(i>leftNum && sigma[i] == '-')            ++plusNum;    }}bool dfs(int cur, int pos, int tot){    if(plusNum-cur > idx-pos)        return false;    if(cur == plusNum){        if(tot*2 == sum) return true;        return false;    }    if(pos<idx && (tot+num[pos])*2 <= sum){        vis[pos] = true;        plus[cur] = num[pos];        if(dfs(cur+1, pos+1, tot+num[pos]))            return true;    }    vis[pos] = false;    if(pos<idx && dfs(cur, pos+1, tot))        return true;    return false;}inline void solve(){    //注意减枝!如果sum为奇数那么直接输出no solution    memset(vis, 0, sizeof(vis));    if((sum&1)==0 && dfs(0, 0, 0)){        int id=1;        ans[0] = plus[0];        for(int i=1; i<idx; ++i){            if(i<leftNum && sigma[i]=='+') {                ans[i] = plus[id++];            } else if(i>leftNum && sigma[i]=='-'){                ans[i] = plus[id++];            }        }        int k=1;        for(int i=0; i<idx; ++i)if(!vis[i]){            while(k<leftNum && sigma[k]=='+' && k<idx) ++k;            while(k>leftNum && sigma[k]=='-' && k<idx) ++k;            ans[k++] = num[i];        }        printf("%d", ans[0]);        for(int i=1; i<idx; ++i)             if(i==leftNum) printf(" = %d",ans[i]);             else printf(" %c %d", sigma[i], ans[i]);        puts("");    }else{        puts("no solution");    }}int main(){    while(gets(str)){        read();        solve();    }    return 0;}




0 0
原创粉丝点击