uva 10317 Equating Equations (搜索题)

uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1258

  又是一道搜索,不过我用了状态压缩来做,开始的时候有两个剪枝加进去,从而3s的时限都超过了。一个是数的和的奇偶性判断,另外一个剪的不明显,那就是统计的时候正或负的和一旦超过整体和的一半时,不用继续加下去。

  这道题麻烦之处主要是它的模拟,输入输出的模拟因为没想到怎么可以更简便,于是就十分暴力的处理了,庆幸这么乱都没有打错。

记录一下代码:

View Code
 1 typedef vector<VI> VVI;
 2 typedef vector<char> VCH;
 3 #define REP(i, n) for (int i = 0; i < (n); i++)
 4 #define REP_1(i, n) for (int i = 1; i <= (n); i++)
 5 #define PB push_back
 6 
 7 VI rec;
 8 VCH op;
 9 int pos, neg;
10 
11 void preProc(char *s) {
12     char buf[3];
13     int x;
14     bool eq = false;
15 //    cout << s << endl;
16     rec.clear();
17     op.clear();
18     pos = 1, neg = 0;
19     while (true) {
20         while (*s && !isdigit(*s)) s++;
21         if (!*s) break;
22         sscanf(s, "%d", &x);
23         rec.PB(x);
24         while (isdigit(*s)) s++;
25         if (!*s) break;
26         sscanf(s, "%s", buf);
27         op.PB(buf[0]);
28         if (buf[0] == '=') eq = true, neg++;
29         else if (eq ^ (buf[0] == '+')) pos++;
30         else neg++;
31     }
32 }
33 
34 void work() {
35     int p, n, cnt;
36     int sum = 0;
37     REP(i, SZ(rec)) {
38         sum += rec[i];
39     }
40     if (sum & 1) { puts("no solution"); return ;}
41     sum >>= 1;
42     VI POS, NEG;
43     POS.clear();
44     NEG.clear();
45     int end = 1 << SZ(rec), sz = SZ(rec);
46     REP(i, end) {
47         p = n = cnt = 0;
48         REP(j, sz) {
49             if (p > sum || n > sum) break;
50             if (i & (1 << j)) p += rec[j], cnt++;
51             else n += rec[j];
52         }
53         if (p == n && (cnt == pos || cnt == neg)) {
54             REP(j, sz)
55                 if (i & (1 << j)) POS.PB(rec[j]);
56                 else NEG.PB(rec[j]);
57             if (cnt == pos) {
58                 int np = 0, nn = 0, no = 0;
59                 printf("%d", POS[np++]);
60                 bool eq = false;
61                 while (no < SZ(op)) {
62                     if (op[no] == '=') {
63                         eq = true;
64                         printf(" = %d", NEG[nn++]);
65                     } else if (op[no] == '+') eq ? printf(" + %d", NEG[nn++]) : printf(" + %d", POS[np++]);
66                     else eq ? printf(" - %d", POS[np++]) : printf(" - %d", NEG[nn++]);
67                     no++;
68                 }
69             } else {
70                 int np = 0, nn = 0, no = 0;
71                 printf("%d", NEG[nn++]);
72                 bool eq = false;
73                 while (no < SZ(op)) {
74                     if (op[no] == '=') {
75                         eq = true;
76                         printf(" = %d", POS[np++]);
77                     } else if (op[no] == '+') eq ? printf(" + %d", POS[np++]) : printf(" + %d", NEG[nn++]);
78                     else eq ? printf(" - %d", NEG[nn++]) : printf(" - %d", POS[np++]);
79                     no++;
80                 }
81             }
82             puts("");
83             return ;
84         }
85     }
86     puts("no solution");
87 }
88 
89 int main() {
90     char buf[10000];
91     while (gets(buf)) {
92         preProc(buf);
93         work();
94     }
95     return 0;
96 }

 

——written by Lyon

转载于:https://www.cnblogs.com/LyonLys/archive/2013/02/28/uva_10317_Lyon.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值