UVa 10317 Equating Equations 解题报告(暴力)

来源:互联网 发布:linux怎么改变当前路径 编辑:程序博客网 时间:2024/05/28 22:09

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
    解题报告:做起来很繁琐的一题。输入部分就很难处理,直接读整行,然后读int和char。
    正题部分,调换顺序使等式成立。等式左边的正号的数和等式右边的减号的数其实是加在一起的。简单来说就是把16个数分成两堆,使两堆相等即可。
    使用状态压缩(或者dfs什么的)枚举可能选择的数,如果刚好是所有数和的一半,那么等式成立,将数字填入相应的位置。代码如下:
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <cmath>#include <queue>#include <vector>#include <map>#include <set>#include <string>#include <iomanip>using namespace std;#define ff(i, n) for(int i=0;i<(n);i++)#define fff(i, n, m) for(int i=(n);i<=(m);i++)#define dff(i, n, m) for(int i=(n);i>=(m);i--)typedef long long LL;typedef unsigned long long ULL;void work();int main(){#ifdef ACM    freopen("in.txt", "r", stdin);#endif // ACM    work();}/***************************************************/char str[222];int pos = 0;char ch;int num[1111111];int readInt(){    while(str[pos] == ' ') pos++;    int ret = 0;    while(isdigit(str[pos]))        ret = ret * 10 + (str[pos++]-'0');    return ret;}char readChar(){    while(str[pos] == ' ') pos++;    return str[pos++];}void work(){    while(gets(str) && str[0])    {        vector<int> vint;        vector<char> vch;        pos = 0;        while(vint.push_back(readInt()), vch.push_back(ch = readChar()), ch);        int n = vint.size();        int sum = 0;        ff(i, n) sum += vint[i];        if(sum&1)        {            puts("no solution");            continue;        }        ch = '+';        vector<int> vp;        vector<int> vpp;        vp.push_back(0);        ff(i, n) if(vch[i] == ch)        {            vp.push_back(i+1);        }        else        {            if(vch[i] == '=')                ch = '-';            vpp.push_back(i+1);        }        int st = -1;        int k = min(vp.size(), n - vp.size());        ff(s, 1<<n)        {            int tmp = 0;            int t = 0;            ff(j, n) if(s&(1<<j))                t++, tmp += vint[j];            if(t == k && tmp == sum/2)            {                st = s;                break;            }        }        if(st == -1)        {            puts("no solution");            continue;        }        if(k != vp.size()) st = ~st;        vector<int> ans;        ff(i, n) ans.push_back(-1);        int sta = 0;        ff(i, n) if(st & (1<<i))            ans[vp[sta++]] = vint[i];        sta = 0, st = ~st;        ff(i, n) if(st & (1<<i))            ans[vpp[sta++]] = vint[i];        printf("%d", ans[0]);        fff(i, 1, n - 1)            printf(" %c %d", vch[i-1], ans[i]);        puts("");    }}


0 0