Назад к лучшим решениям Status: AC, problem ZTM, contest ZEL07. By werewolf (Werewolf), 2007-03-12 01:32:44.
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define MAX_CACHE 5
  5.  
  6. enum
  7. {
  8. di = -1,
  9. um = 0,
  10. da = 1
  11. };
  12. enum
  13. {
  14. shsh = 0,
  15. umum,
  16. umda,
  17. umdi,
  18. daum,
  19. dada,
  20. dadi,
  21. dium,
  22. dida,
  23. didi,
  24. symmax
  25. };
  26. char *sym2[] = {
  27. "shsh",
  28. "umum",
  29. "umda",
  30. "umdi",
  31. "daum",
  32. "dada",
  33. "dadi",
  34. "dium",
  35. "dida",
  36. "didi",
  37. };
  38. char * sym1[] = {
  39. "di",
  40. "um",
  41. "da",
  42. };
  43.  
  44. #define abs(a) ((a)<0?-(a):a)
  45. #define decode_sym1(a) ((a)==0?di:((a)==1?um:da))
  46. #define encode_sym1(a) ((a)==-1?0:((a)==0?1:2))
  47. void decodeSym2(int sym2, int * str)
  48. {
  49. switch(sym2)
  50. {
  51. case shsh:
  52. break;
  53. case umum:
  54. str[0] = um;
  55. str[1] = um;
  56. break;
  57. case umda:
  58. str[0] = um;
  59. str[1] = da;
  60. break;
  61. case umdi:
  62. str[0] = um;
  63. str[1] = di;
  64. break;
  65. case daum:
  66. str[0] = da;
  67. str[1] = um;
  68. break;
  69. case dada:
  70. str[0] = da;
  71. str[1] = da;
  72. break;
  73. case dadi:
  74. str[0] = da;
  75. str[1] = di;
  76. break;
  77. case dium:
  78. str[0] = di;
  79. str[1] = um;
  80. break;
  81. case dida:
  82. str[0] = di;
  83. str[1] = da;
  84. break;
  85. case didi:
  86. str[0] = di;
  87. str[1] = di;
  88. break;
  89. }
  90. }
  91. int isMinimized(int *str, int count, int n)
  92. {
  93. int i, sum = 0;
  94. for(i = 0; i < count; i++)
  95. {
  96. sum += str[i];
  97. if(sum == n)
  98. return 1;
  99. }
  100. return 0;
  101. }
  102. int minimize(int *str, int count, int n)
  103. {
  104. int i, d, diff = 0, sum = 0;
  105. for(i = 0; i < count; i++)
  106. {
  107. sum += str[i];
  108. if(sum == n)
  109. return 1;
  110. if(abs(sum-n) <= 2)
  111. {
  112. diff = sum-n;
  113. d = i;
  114. }
  115. }
  116. for(i = 0; i <= d; i++)
  117. {
  118. switch(diff)
  119. {
  120. case -2:
  121. if(str[i] == di)
  122. {
  123. str[i]=da;
  124. return 1;
  125. }
  126. break;
  127. case -1:
  128. if(str[i] == di)
  129. {
  130. str[i]=um;
  131. return 1;
  132. }else
  133. if(str[i] == um)
  134. {
  135. str[i]=da;
  136. return 1;
  137. }
  138. break;
  139. case 1:
  140. if(str[i] == um)
  141. {
  142. str[i]=di;
  143. return 1;
  144. }else
  145. if(str[i] == da)
  146. {
  147. str[i]=um;
  148. return 1;
  149. }
  150. break;
  151. case 2:
  152. if(str[i] == da)
  153. {
  154. str[i]=di;
  155. return 1;
  156. }
  157. break;
  158. }
  159. }
  160. return 0;
  161. }
  162. int decodeState(int state, int * cache, int * cache_size)
  163. {
  164. int state3[MAX_CACHE+2] = {0};
  165. int i = 0, q = -1;
  166. *cache_size = 0;
  167. for(i = 0; i < MAX_CACHE+2; i++)
  168. {
  169. state3[i] = state%3;
  170. state /= 3;
  171. if(state == 0) break;
  172. }
  173. if(i < 1) return -1;
  174. if(state3[i] < 1) return -1;
  175. q = (state3[i]-1)*3+state3[i-1];
  176. i-=2;
  177.  
  178. for(;i >= 0; i--)
  179. {
  180. cache[(*cache_size)++] = decode_sym1(state3[i]);
  181. }
  182. return q;
  183.  
  184. }
  185. int encodeState(int q, int * cache, int cache_size)
  186. {
  187. int p = 1;
  188. int state = 0;
  189. int i;
  190. for(i = cache_size-1;i >=0; i--)
  191. {
  192. state += encode_sym1(cache[i])*p;
  193. p*=3;
  194. }
  195. state += (q/3+1)*p*3+(q%3)*p;
  196. return state;
  197. }
  198. #define map_zero_state(s) ((s)==3?0:(s))
  199. int * shiftCache(int * cache, int cache_size)
  200. {
  201. memmove(cache, cache+1, (cache_size-1)*sizeof(int));
  202. return cache;
  203. }
  204. void printCommand2(int q, int * cache, int cache_size, int sym, int move)
  205. {
  206. int state = encodeState(q, cache, cache_size);
  207. printf("%03d %s %s\n", map_zero_state(state), sym2[sym], sym1[encode_sym1(move)]);
  208. }
  209.  
  210. void processVariants()
  211. {
  212. int state, sym, move;
  213. int q, cache[10]={0}, cache_size;
  214. for(state = 0; state <= 999; state++)
  215. {
  216. q = decodeState(state, cache, &cache_size);
  217. if(q < 0)
  218. continue;
  219. if(q > 0 && cache_size == 0)
  220. continue;
  221.  
  222. for(sym = 0; sym < symmax; sym++)
  223. {
  224. q = decodeState(state, cache, &cache_size);
  225. if(sym == shsh && cache_size == 0)
  226. continue;
  227.  
  228. if(sym == shsh)
  229. {
  230. move = cache[0];
  231. printf("%03d %s ", map_zero_state(state), sym2[sym]);
  232. printCommand2(0, shiftCache(cache, cache_size), cache_size-1, shsh, move);
  233. continue;
  234. }
  235. if(q > 0)
  236. {
  237. move = cache[0];
  238.  
  239. printf("%03d %s ", map_zero_state(state), sym2[sym]);
  240. printCommand2(q+move, shiftCache(cache, cache_size), cache_size-1, sym, move);
  241. continue;
  242. }
  243. if(q == 0)
  244. {
  245. printf("%03d %s ", map_zero_state(state), sym2[sym]);
  246. if(cache_size == MAX_CACHE)
  247. {
  248. minimize(cache, cache_size, 0);
  249. move = cache[0];
  250. printCommand2(move<0?0:move, shiftCache(cache, cache_size), cache_size-1, sym, move);
  251. continue;
  252. }
  253. /*
  254. if(cache_size > 0 && isMinimized(cache, cache_size, 0))
  255. {
  256. move = cache[0];
  257. printCommand2(move<0?0:move, shiftCache(cache, cache_size), cache_size-1, sym, move);
  258. continue;
  259. }*/
  260. decodeSym2(sym, cache+cache_size);
  261. cache_size+=2;
  262. minimize(cache, cache_size, 1);
  263. move = cache[0];
  264. printCommand2(0, shiftCache(cache, cache_size), cache_size-1, shsh, move);
  265. continue;
  266. }
  267. }
  268. }
  269. }
  270. int main()
  271. {
  272. processVariants();
  273. return 0;
  274. }