记录编号 262369 评测结果 AAAAAAAAAA
题目名称 [NOI 2000]算符破译 最终得分 100
用户昵称 Gravatarppfish 是否通过 通过
代码语言 C++ 运行时间 5.004 s
提交时间 2016-05-20 16:32:19 内存使用 0.34 MiB
显示代码纯文本
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. template<typename T>inline void Read(T &x)
  5. {
  6. int f = 1;
  7. char t = getchar();
  8. while (t < '0' || t > '9') {
  9. if (t == '-') f = -1;
  10. t = getchar();
  11. }
  12. x = 0;
  13. while (t >= '0' && t <= '9') {
  14. x = x * 10 + t - '0';
  15. t = getchar();
  16. }
  17. x *= f;
  18. }
  19.  
  20. template<typename T>inline void Write(T x)
  21. {
  22. static int output[20];
  23. int top = 0;
  24. if (x < 0) putchar('-'), x = -x;
  25. do {
  26. output[++top] = x % 10;
  27. x /= 10;
  28. } while (x > 0);
  29. while (top > 0) putchar('0' + output[top --]);
  30. putchar('\n');
  31. }
  32.  
  33. template<typename T>inline void chkmin(T &x, T y) { if (x > y) x = y; }
  34. template<typename T>inline void chkmax(T &x, T y) { if (x < y) x = y; }
  35.  
  36. const int maxn = 1005;
  37. const int sigma = 13;
  38. const int maxlen = 14;
  39. const char uti[] = "=+*0123456789";
  40.  
  41. int n;
  42. int len[maxn];
  43. char str[maxn][maxlen];
  44.  
  45. bool ban[sigma];
  46. bool fst[sigma];
  47. bool end[sigma];
  48. bool ineql[sigma];
  49. bool okeql[sigma];
  50. bool adj[sigma][sigma];
  51. int st[maxn];
  52. int ed[maxn];
  53. vector<pair<int, int> > neighbor[sigma];
  54.  
  55. bool used[sigma];
  56. int to[sigma];
  57.  
  58. bool nosol = true;
  59. int res[sigma][sigma];
  60.  
  61. void input()
  62. {
  63. Read(n);
  64. for (int i = 1; i <= n; i++) {
  65. scanf("%s", str[i] + 1);
  66. len[i] = strlen(str[i] + 1);
  67. for (int j = 1; j <= len[i]; j++) {
  68. if (str[i][j] - 'a' >= sigma) {
  69. puts("noway");
  70. exit(0);
  71. }
  72. }
  73. }
  74. }
  75.  
  76. long long calc(char *re, int l, int r)
  77. {
  78. static long long num[maxlen];
  79. static long long qn[maxlen];
  80. static char opr[maxlen];
  81. static char s[maxlen];
  82. int ol = 0;
  83. int nl = 0;
  84. int nt = 0;
  85. long long cnt;
  86. for (int i = l; i <= r; i++) {
  87. if (isalpha(re[i])) {
  88. s[i] = uti[to[re[i] - 'a']];
  89. } else {
  90. s[i] = re[i];
  91. }
  92. }
  93. if (!isdigit(s[l]) || !isdigit(s[r])) return -1;
  94. for (int i = l; i <= r; i++) {
  95. if (!isdigit(s[i])) opr[++ol] = s[i];
  96. else {
  97. cnt = s[i] - '0';
  98. while (i + 1 <= r && isdigit(s[i + 1])) {
  99. cnt = cnt * 10 + s[i + 1] - '0';
  100. i ++;
  101. }
  102. num[++nl] = cnt;
  103. }
  104. }
  105. qn[++nt] = num[1];
  106. for (int i = 1; i <= ol; i++) {
  107. if (opr[i] == '*') {
  108. qn[nt] = qn[nt] * num[i + 1];
  109. } else {
  110. qn[++nt] = num[i + 1];
  111. }
  112. }
  113. long long res = 0;
  114. while (nt > 0) res += qn[nt --];
  115. return res;
  116. }
  117.  
  118. void prepare()
  119. {
  120. static int appear[sigma];
  121. for (int i = 0; i < sigma; i++) okeql[i] = true;
  122. for (int i = 1; i <= n; i++) {
  123. memset(appear, 0, sizeof(appear));
  124. for (int j = 1; j <= len[i]; j++) {
  125. appear[str[i][j] - 'a'] ++;
  126. ineql[str[i][j] - 'a'] = true;
  127. }
  128. for (int j = 0; j < sigma; j++) {
  129. okeql[j] &= (appear[j] == 1);
  130. okeql[j] &= (str[i][1] - 'a' != j);
  131. okeql[j] &= (str[i][len[i]] - 'a' != j);
  132. }
  133. for (int j = 1; j < len[i]; j++) {
  134. adj[str[i][j] - 'a'][str[i][j + 1] - 'a'] = true;
  135. adj[str[i][j + 1] - 'a'][str[i][j] - 'a'] = true;
  136. }
  137. fst[str[i][1] - 'a'] = true;
  138. end[str[i][len[i]] - 'a'] = true;
  139. }
  140. static set<pair<int, int> > g[sigma];
  141. pair<int, int> foo;
  142. for (int i = 1; i <= n; i++) {
  143. for (int j = 1; j < len[i]; j++) {
  144. g[str[i][j] - 'a'].insert(make_pair(j == 1 ? -1 : str[i][j - 1] - 'a', str[i][j + 1] - 'a'));
  145. }
  146. }
  147. for (int i = 0; i < sigma; i++) {
  148. for (set<pair<int, int> >::iterator it = g[i].begin(); it != g[i].end(); it++) {
  149. neighbor[i].push_back(*it);
  150. }
  151. }
  152. }
  153.  
  154. vector<int> remain;
  155.  
  156. void fillmax(char s[maxlen], int l, int r)
  157. {
  158. for (int i = l; i <= r; i++) {
  159. if (to[s[i] - 'a'] == -1) {
  160. s[i] = '9';
  161. }
  162. }
  163. }
  164.  
  165. void fillmin(char s[maxlen], int l, int r)
  166. {
  167. for (int i = l, last = -1; i <= r + 1; i++) {
  168. if (to[s[i] - 'a'] == -1 && last == -1) last = i;
  169. if ((to[s[i] - 'a'] != -1 || i == r + 1) && last != -1) {
  170. if (i - last == 1) {
  171. s[last] = '0';
  172. } else {
  173. s[last] = '1';
  174. for (int j = last + 1; j < i; j++) s[j] = '0';
  175. }
  176. last = -1;
  177. }
  178. }
  179. }
  180.  
  181. void split()
  182. {
  183. for (int i = 1; i <= n; i++) {
  184. for (int j = 1; j <= len[i]; j++) {
  185. if (to[str[i][j] - 'a'] == 0) {
  186. ed[i] = j - 1;
  187. st[i] = j + 1;
  188. break;
  189. }
  190. }
  191. }
  192. }
  193.  
  194. bool checkrange()
  195. {
  196. char tmp[maxlen];
  197. for (int i = 0; i < sigma; i++) {
  198. if (to[i] != -1) {
  199. for (int j = i; j < sigma; j++) {
  200. if (to[j] != -1) {
  201. if (adj[i][j]) {
  202. return false;
  203. }
  204. }
  205. }
  206. }
  207. }
  208. long long lmax, rmax;
  209. long long lmin, rmin;
  210. for (int i = 1; i <= n; i++) {
  211. memcpy(tmp, str[i], sizeof(str[i]));
  212. fillmax(tmp, 1, len[i]);
  213. lmax = calc(tmp, 1, ed[i]);
  214. rmax = calc(tmp, st[i], len[i]);
  215. memcpy(tmp, str[i], sizeof(str[i]));
  216. fillmin(tmp, 1, len[i]);
  217. lmin = calc(tmp, 1, ed[i]);
  218. rmin = calc(tmp, st[i], len[i]);
  219. if (lmax < rmin || lmin > rmax) return false;
  220. }
  221. return true;
  222. }
  223.  
  224. bool prezero()
  225. {
  226. int pr, nx;
  227. for (int i = 0; i < sigma; i++) {
  228. if (to[i] == 3) {
  229. for (int j = 0; j < (int)neighbor[i].size(); j++) {
  230. pr = neighbor[i][j].first;
  231. nx = neighbor[i][j].second;
  232. if ((pr == -1 || (to[pr] < 3 && to[pr] != -1)) && (to[nx] == -1 || to[nx] >= 3)) {
  233. return true;
  234. }
  235. }
  236. }
  237. }
  238. return false;
  239. }
  240.  
  241. bool checkall()
  242. {
  243. long long r1, r2;
  244. for (int i = 1; i <= n; i++) {
  245. r1 = calc(str[i], 1, ed[i]);
  246. r2 = calc(str[i], st[i], len[i]);
  247. if (r1 == -1 || r2 == -1 || r1 != r2) return false;
  248. }
  249. return true;
  250. }
  251.  
  252. void dfs(int cur)
  253. {
  254. if (cur == (int)remain.size()) {
  255. if (checkall()) {
  256. nosol = false;
  257. for (int i = 0; i < sigma; i++) {
  258. if (to[i] != -1) {
  259. res[i][to[i]] ++;
  260. } else {
  261. ban[i] = true;
  262. }
  263. }
  264. }
  265. return;
  266. }
  267. for (int i = 3; i < sigma; i++) {
  268. if (!used[i]) {
  269. used[i] = true;
  270. to[remain[cur]] = i;
  271. if (i != 3 || (i == 3 && !prezero())) dfs(cur + 1);
  272. used[i] = false;
  273. to[remain[cur]] = -1;
  274. }
  275. }
  276. }
  277.  
  278. void enumopr(int cur)
  279. {
  280. if (cur == 1) split();
  281. if (cur == 3) {
  282. if (checkrange()) {
  283. remain.clear();
  284. for (int i = 0; i < sigma; i++) {
  285. if (to[i] == -1 && ineql[i]) {
  286. remain.push_back(i);
  287. }
  288. }
  289. dfs(0);
  290. }
  291. return;
  292. }
  293. for (int i = 0; i < sigma; i++) {
  294. if (cur == 0 && !okeql[i]) continue;
  295. if (to[i] == -1 && !fst[i] && !end[i]) {
  296. to[i] = cur;
  297. enumopr(cur + 1);
  298. to[i] = -1;
  299. }
  300. }
  301. }
  302.  
  303. void solve()
  304. {
  305. memset(to, -1, sizeof(to));
  306. enumopr(0);
  307. for (int i = 0; i < sigma; i++) {
  308. if (ban[i]) continue;
  309. int cert = -1;
  310. bool flag = true;
  311. for (int j = 0; j < sigma; j++) {
  312. if (res[i][j] > 0) {
  313. if (cert == -1) cert = j;
  314. else flag = false;
  315. }
  316. }
  317. if (cert != -1 && flag) {
  318. printf("%c%c\n", 'a' + i, uti[cert]);
  319. }
  320. }
  321. if (nosol) puts("noway");
  322. }
  323.  
  324. int main()
  325. {
  326. //#ifndef ONLINE_JUDGE
  327. freopen("equation.in", "r", stdin);
  328. freopen("equation.out", "w", stdout);
  329. //#endif
  330.  
  331. input();
  332. prepare();
  333. solve();
  334.  
  335. //#ifndef ONLINE_JUDGE
  336. fclose(stdin);
  337. fclose(stdout);
  338. //#endif
  339. return 0;
  340. }