Source code for submission s903

ladybug.cpp

  1. #include <algorithm>
  2. #include <cctype>
  3. #include <cmath>
  4. #include <complex>
  5. #include <cstdio>
  6. #include <cstring>
  7. #include <iomanip>
  8. #include <iostream>
  9. #include <list>
  10. #include <map>
  11. #include <queue>
  12. #include <set>
  13. #include <sstream>
  14. #include <stack>
  15. #include <string>
  16. #include <utility>
  17. #include <vector>
  18. using namespace std;
  19.  
  20. #define DEBUG(x) cout << ">>> " << #x << " : " << x << endl;
  21. #define REP(i,a) for (int i = 0; i < (a); ++i)
  22. #define FOR(i,a,b) for (int i = (a); i <= (b); ++i)
  23. #define FORD(i,a,b) for (int i = (a); i >= (b); --i)
  24. inline bool EQ(double a, double b) { return fabs(a-b) < 1e-9; }
  25.  
  26. const int INF = 1<<29;
  27. typedef long long ll;
  28. ///////////////////////////////////////////////////////////////////////////
  29.  
  30. const int NA = 5, MAX = 1000;
  31. const int PLUS = 0, MINUS = 1, MULT = 2, DIV = 3, EQU = 4;
  32. int oper_ind(char c)
  33. {
  34. switch(c)
  35. {
  36. case '+': return PLUS;
  37. case '-': return MINUS;
  38. case '*': return MULT;
  39. case '/': return DIV;
  40. case '=': return EQU;
  41. }
  42. DEBUG("AAAAAAAAAAAAAAAA");
  43. return -1;
  44. }
  45.  
  46. bool numbers[10];
  47. bool opers[5];
  48.  
  49. int step;
  50. int visited[MAX][MAX][6][3];
  51. int dp[MAX][MAX][6][3];
  52.  
  53. char available[100];
  54. int N;
  55.  
  56. struct State
  57. {
  58. int disp, value, oper, state;
  59. State(int _d, int _v, int _o, int _s):
  60. disp(_d), value(_v), oper(_o), state(_s) {}
  61.  
  62. bool is_visited() const
  63. {
  64. return visited[disp][value][oper][state] == step;
  65. }
  66.  
  67. void visit(int val) const
  68. {
  69. visited[disp][value][oper][state] = step;
  70. dp[disp][value][oper][state] = val;
  71. }
  72.  
  73. int get_val() const
  74. {
  75. return dp[disp][value][oper][state];
  76. }
  77.  
  78. bool is_valid() const
  79. {
  80. return disp >= 0 && disp < MAX && value >= 0 && value < MAX;
  81. }
  82.  
  83. string str() const
  84. {
  85. ostringstream os;
  86. os << "Disp: " << disp << " Value: " << value << " Oper: " << oper << " State: " << state;
  87. return os.str();
  88. }
  89. };
  90.  
  91. queue<State> manage;
  92. int update(const State & s, int val)
  93. {
  94. if (s.is_visited())
  95. return -1;
  96. s.visit(val);
  97. manage.push(s);
  98. if (s.disp == N)
  99. return val;
  100. return -1;
  101. }
  102.  
  103. int eval(int a, int oper, int b)
  104. {
  105. if (oper == PLUS) return a+b;
  106. if (oper == MINUS) return a-b;
  107. if (oper == MULT) return a*b;
  108. if (oper == DIV) return b?a/b:-1;
  109. DEBUG("AAAAAAAAAAAAAAAAAAAAA");
  110. return -1;
  111. }
  112.  
  113. int main()
  114. {
  115. while (scanf("%s %d", available, &N) == 2)
  116. {
  117. if (!N) { printf("0\n"); continue; }
  118.  
  119. ++step;
  120. memset(numbers, 0, sizeof(numbers));
  121. memset(opers, 0, sizeof(opers));
  122. int len = strlen(available);
  123. REP(i, len)
  124. {
  125. if (available[i] >= '0' && available[i] <= '9')
  126. numbers[available[i]-'0'] = true;
  127. else
  128. opers[oper_ind(available[i])] = true;
  129. }
  130.  
  131. manage = queue<State>();
  132. update(State(0, 0, NA, 0), 0);
  133. int result = -1;
  134. while (!manage.empty())
  135. {
  136. State s = manage.front();
  137. manage.pop();
  138. int val = s.get_val();
  139. if (s.state == 0)
  140. {
  141. // press num
  142. REP(i, 10)
  143. {
  144. if (!numbers[i]) continue;
  145. State s2 = s;
  146. s2.disp = i;
  147. s2.state = 1;
  148. if ((result = update(s2, val+1)) != -1) goto FOUND;
  149. }
  150. // press op
  151. REP(i, NA)
  152. {
  153. if (!opers[i]) continue;
  154. State s2 = s;
  155. s2.oper = i;
  156. s2.state = 2;
  157. if ((result = update(s2, val+1)) != -1) goto FOUND;
  158. }
  159. }
  160. else if (s.state == 1)
  161. {
  162. // press numb
  163. REP(i, 10)
  164. {
  165. if (!numbers[i]) continue;
  166. State s2 = s;
  167. s2.disp = 10*s2.disp+i;
  168. if (!s2.is_valid()) continue;
  169. if ((result = update(s2, val+1)) != -1) goto FOUND;
  170. }
  171. // press op
  172. REP(i, NA)
  173. {
  174. if (!opers[i]) continue;
  175. State s2 = s;
  176. if (s2.oper != EQU && s2.oper != NA)
  177. s2.disp = eval(s2.value, s2.oper, s2.disp);
  178. s2.oper = i;
  179. s2.value = s2.disp;
  180. s2.state = 2;
  181. if (!s2.is_valid()) continue;
  182. if ((result = update(s2, val+1)) != -1) goto FOUND;
  183. }
  184. }
  185. else
  186. {
  187. // press numb
  188. REP(i, 10)
  189. {
  190. if (!numbers[i]) continue;
  191. State s2 = s;
  192. s2.disp = i;
  193. s2.state = 1;
  194. if ((result = update(s2, val+1)) != -1) goto FOUND;
  195. }
  196. // press op
  197. REP(i, NA)
  198. {
  199. if (!opers[i]) continue;
  200. State s2 = s;
  201. if (i == EQU && s2.oper != EQU)
  202. s2.disp = eval(s2.value, s2.oper, s2.disp);
  203. s2.oper = i;
  204. s2.value = s2.disp;
  205. if (!s2.is_valid()) continue;
  206. if ((result = update(s2, val+1)) != -1) goto FOUND;
  207. }
  208. }
  209. }
  210.  
  211. FOUND:
  212. if (result == -1)
  213. printf("impossible\n");
  214. else
  215. printf("%d\n", result);
  216. }
  217.  
  218. return 0;
  219. }
  220.