UVa 10317 - Equating Equations(DFS)

题意

不改变符号顺序,问能不能交换数字的位置使等式成立。

思路

一开始看数据量这么小果断暴力枚举全排列然后检查,爽快地TLE了。后来想了一下,可以把左边的-号的数字都移到右边,这样两边都是正的数字,只要找出sum / 2的数字组成就行。

这里可以写DFS也可以写DP。

然后就是输出。

取出符号,如果在等号左边,而且符号是+,之后填上我们找到的数字,如果是-,就填上我们找到数字之外的数字(就是移到右边是正的数字)

等号右边相反。

但是需要考虑的情况有点多,主要是越界的问题。代码写得很不优雅,大家参考思路就行。。

代码

  
  
  
  
  1. #include <cstdio>
  2. #include <stack>
  3. #include <set>
  4. #include <iostream>
  5. #include <string>
  6. #include <vector>
  7. #include <cctype>
  8. #include <algorithm>
  9. #include <cstdlib>
  10. #include <queue>
  11. #include <functional>
  12. #include <cstring>
  13. #include <string>
  14. #include <sstream>
  15. #include <map>
  16. #include <cmath>
  17. #define LL long long
  18. #define lowbit(x) ((x) & (-x))
  19. #define MP(a, b) make_pair(a, b)
  20. #define MS(arr, num) memset(arr, num, sizeof(arr))
  21. #define PB push_back
  22. #define ROP freopen("input.txt", "r", stdin);
  23. const double PI = acos(-1.0);
  24. const int INF = 0x3f3f3f3f;
  25. using namespace std;
  26. const int MAXN = 30 + 5;
  27. typedef pair<int, int> pii;
  28. typedef vector<int>::iterator viti;
  29. typedef vector<pii>::iterator vitii;
  30. int vis[MAXN], succeed, sum, ans[MAXN], cnt;
  31. vector<int> num, sym, rnum;
  32. char str[10000];
  33. bool lpos, rpos;
  34. void DFS(int curSum, int cur, int curCnt)
  35. {
  36. for (int i = cur; i < num.size(); i++)
  37. {
  38. if (succeed) return;
  39. if (curSum + num[i] > sum) return;
  40. if (curSum + num[i] == sum && curCnt + 1 == cnt)
  41. {
  42. ans[curCnt] = i;
  43. succeed = 1;
  44. return;
  45. }
  46. ans[curCnt] = i;
  47. DFS(curSum + num[i], i + 1, curCnt + 1);
  48. }
  49. }
  50. void OutPut()
  51. {
  52. if (!succeed) printf("no solution");
  53. else
  54. {
  55. for (int i = 0; i < cnt; i++) vis[ans[i]] = 1;
  56. for (int i = 0; i < num.size(); i++)
  57. if (!vis[i]) rnum.push_back(num[i]);
  58. int i = 0, j = 0, k = 0;
  59. char ch;
  60. if (lpos)
  61. {
  62. ch = sym[j++];
  63. printf("%c", ch);
  64. if (ch == '+') printf("%d", num[ans[i++]]);
  65. if (ch == '-') printf("%d", rnum[k++]);
  66. }
  67. else printf("%d", num[ans[i++]]);
  68. ch = sym[j++];
  69. while (ch != '=')
  70. {
  71. printf(" %c ", ch);
  72. if (ch == '-') printf("%d", rnum[k++]);
  73. if (ch == '+') printf("%d", num[ans[i++]]);
  74. ch = sym[j++];
  75. }
  76. printf(" = ");
  77. if (rpos)
  78. {
  79. ch = sym[j++];
  80. printf("%c", ch);
  81. if (ch == '-') printf("%d", num[ans[i++]]);
  82. if (ch == '+') printf("%d", rnum[k++]);
  83. if (j == sym.size()) return;
  84. }
  85. else printf("%d", rnum[k++]);
  86. if (j == sym.size()) return;
  87. ch = sym[j++];
  88. while (1)
  89. {
  90. printf(" %c ", ch);
  91. if (ch == '-') printf("%d", num[ans[i++]]);
  92. if (ch == '+') printf("%d", rnum[k++]);
  93. if (j == sym.size()) return;
  94. ch = sym[j++];
  95. }
  96. }
  97. }
  98. int main()
  99. {
  100. //ROP;
  101. int i, j;
  102. char ch;
  103. while (gets(str))
  104. {
  105. MS(vis, 0);
  106. succeed = sum = cnt = 0;
  107. num.clear();
  108. rnum.clear();
  109. sym.clear();
  110. lpos = rpos = false;
  111. int a = 0;
  112. char last = 0;
  113. for (i = 0; str[i] != '='; i++)
  114. {
  115. if (isdigit(str[i]))
  116. {
  117. if (last == '+' || last == 0) cnt++;
  118. a = atoi(&str[i]);
  119. num.push_back(a); sum += a;
  120. while (isdigit(str[i])) i++;
  121. }
  122. if (str[i] == '+' || str[i] == '-')
  123. {
  124. if (num.empty()) lpos = true;
  125. last = str[i];
  126. sym.push_back(last);
  127. }
  128. }
  129. sym.push_back(str[i]);
  130. int temp = num.size(); //用于标记当前的数量
  131. last = 0;
  132. for(; i < strlen(str); i++)
  133. {
  134. if (isdigit(str[i]))
  135. {
  136. if (last == '-') cnt++;
  137. a = atoi(&str[i]);
  138. num.push_back(a); sum += a;
  139. while (isdigit(str[i])) i++;
  140. }
  141. if (str[i] == '+' || str[i] == '-')
  142. {
  143. if (num.size() == temp) rpos = true;
  144. last = str[i];
  145. sym.push_back(last);
  146. }
  147. }
  148. if (sum & 1)
  149. {
  150. printf("no solution\n");
  151. continue;
  152. }
  153. sum /= 2;
  154. sort(num.begin(), num.end());
  155. DFS(0, 0, 0);
  156. OutPut();
  157. puts("");
  158. }
  159. return 0;
  160. }

你可能感兴趣的:(ACM,uva)