记录编号 |
262369 |
评测结果 |
AAAAAAAAAA |
题目名称 |
[NOI 2000]算符破译 |
最终得分 |
100 |
用户昵称 |
ppfish |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
5.004 s |
提交时间 |
2016-05-20 16:32:19 |
内存使用 |
0.34 MiB |
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
template<typename T>inline void Read(T &x)
{
int f = 1;
char t = getchar();
while (t < '0' || t > '9') {
if (t == '-') f = -1;
t = getchar();
}
x = 0;
while (t >= '0' && t <= '9') {
x = x * 10 + t - '0';
t = getchar();
}
x *= f;
}
template<typename T>inline void Write(T x)
{
static int output[20];
int top = 0;
if (x < 0) putchar('-'), x = -x;
do {
output[++top] = x % 10;
x /= 10;
} while (x > 0);
while (top > 0) putchar('0' + output[top --]);
putchar('\n');
}
template<typename T>inline void chkmin(T &x, T y) { if (x > y) x = y; }
template<typename T>inline void chkmax(T &x, T y) { if (x < y) x = y; }
const int maxn = 1005;
const int sigma = 13;
const int maxlen = 14;
const char uti[] = "=+*0123456789";
int n;
int len[maxn];
char str[maxn][maxlen];
bool ban[sigma];
bool fst[sigma];
bool end[sigma];
bool ineql[sigma];
bool okeql[sigma];
bool adj[sigma][sigma];
int st[maxn];
int ed[maxn];
vector<pair<int, int> > neighbor[sigma];
bool used[sigma];
int to[sigma];
bool nosol = true;
int res[sigma][sigma];
void input()
{
Read(n);
for (int i = 1; i <= n; i++) {
scanf("%s", str[i] + 1);
len[i] = strlen(str[i] + 1);
for (int j = 1; j <= len[i]; j++) {
if (str[i][j] - 'a' >= sigma) {
puts("noway");
exit(0);
}
}
}
}
long long calc(char *re, int l, int r)
{
static long long num[maxlen];
static long long qn[maxlen];
static char opr[maxlen];
static char s[maxlen];
int ol = 0;
int nl = 0;
int nt = 0;
long long cnt;
for (int i = l; i <= r; i++) {
if (isalpha(re[i])) {
s[i] = uti[to[re[i] - 'a']];
} else {
s[i] = re[i];
}
}
if (!isdigit(s[l]) || !isdigit(s[r])) return -1;
for (int i = l; i <= r; i++) {
if (!isdigit(s[i])) opr[++ol] = s[i];
else {
cnt = s[i] - '0';
while (i + 1 <= r && isdigit(s[i + 1])) {
cnt = cnt * 10 + s[i + 1] - '0';
i ++;
}
num[++nl] = cnt;
}
}
qn[++nt] = num[1];
for (int i = 1; i <= ol; i++) {
if (opr[i] == '*') {
qn[nt] = qn[nt] * num[i + 1];
} else {
qn[++nt] = num[i + 1];
}
}
long long res = 0;
while (nt > 0) res += qn[nt --];
return res;
}
void prepare()
{
static int appear[sigma];
for (int i = 0; i < sigma; i++) okeql[i] = true;
for (int i = 1; i <= n; i++) {
memset(appear, 0, sizeof(appear));
for (int j = 1; j <= len[i]; j++) {
appear[str[i][j] - 'a'] ++;
ineql[str[i][j] - 'a'] = true;
}
for (int j = 0; j < sigma; j++) {
okeql[j] &= (appear[j] == 1);
okeql[j] &= (str[i][1] - 'a' != j);
okeql[j] &= (str[i][len[i]] - 'a' != j);
}
for (int j = 1; j < len[i]; j++) {
adj[str[i][j] - 'a'][str[i][j + 1] - 'a'] = true;
adj[str[i][j + 1] - 'a'][str[i][j] - 'a'] = true;
}
fst[str[i][1] - 'a'] = true;
end[str[i][len[i]] - 'a'] = true;
}
static set<pair<int, int> > g[sigma];
pair<int, int> foo;
for (int i = 1; i <= n; i++) {
for (int j = 1; j < len[i]; j++) {
g[str[i][j] - 'a'].insert(make_pair(j == 1 ? -1 : str[i][j - 1] - 'a', str[i][j + 1] - 'a'));
}
}
for (int i = 0; i < sigma; i++) {
for (set<pair<int, int> >::iterator it = g[i].begin(); it != g[i].end(); it++) {
neighbor[i].push_back(*it);
}
}
}
vector<int> remain;
void fillmax(char s[maxlen], int l, int r)
{
for (int i = l; i <= r; i++) {
if (to[s[i] - 'a'] == -1) {
s[i] = '9';
}
}
}
void fillmin(char s[maxlen], int l, int r)
{
for (int i = l, last = -1; i <= r + 1; i++) {
if (to[s[i] - 'a'] == -1 && last == -1) last = i;
if ((to[s[i] - 'a'] != -1 || i == r + 1) && last != -1) {
if (i - last == 1) {
s[last] = '0';
} else {
s[last] = '1';
for (int j = last + 1; j < i; j++) s[j] = '0';
}
last = -1;
}
}
}
void split()
{
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= len[i]; j++) {
if (to[str[i][j] - 'a'] == 0) {
ed[i] = j - 1;
st[i] = j + 1;
break;
}
}
}
}
bool checkrange()
{
char tmp[maxlen];
for (int i = 0; i < sigma; i++) {
if (to[i] != -1) {
for (int j = i; j < sigma; j++) {
if (to[j] != -1) {
if (adj[i][j]) {
return false;
}
}
}
}
}
long long lmax, rmax;
long long lmin, rmin;
for (int i = 1; i <= n; i++) {
memcpy(tmp, str[i], sizeof(str[i]));
fillmax(tmp, 1, len[i]);
lmax = calc(tmp, 1, ed[i]);
rmax = calc(tmp, st[i], len[i]);
memcpy(tmp, str[i], sizeof(str[i]));
fillmin(tmp, 1, len[i]);
lmin = calc(tmp, 1, ed[i]);
rmin = calc(tmp, st[i], len[i]);
if (lmax < rmin || lmin > rmax) return false;
}
return true;
}
bool prezero()
{
int pr, nx;
for (int i = 0; i < sigma; i++) {
if (to[i] == 3) {
for (int j = 0; j < (int)neighbor[i].size(); j++) {
pr = neighbor[i][j].first;
nx = neighbor[i][j].second;
if ((pr == -1 || (to[pr] < 3 && to[pr] != -1)) && (to[nx] == -1 || to[nx] >= 3)) {
return true;
}
}
}
}
return false;
}
bool checkall()
{
long long r1, r2;
for (int i = 1; i <= n; i++) {
r1 = calc(str[i], 1, ed[i]);
r2 = calc(str[i], st[i], len[i]);
if (r1 == -1 || r2 == -1 || r1 != r2) return false;
}
return true;
}
void dfs(int cur)
{
if (cur == (int)remain.size()) {
if (checkall()) {
nosol = false;
for (int i = 0; i < sigma; i++) {
if (to[i] != -1) {
res[i][to[i]] ++;
} else {
ban[i] = true;
}
}
}
return;
}
for (int i = 3; i < sigma; i++) {
if (!used[i]) {
used[i] = true;
to[remain[cur]] = i;
if (i != 3 || (i == 3 && !prezero())) dfs(cur + 1);
used[i] = false;
to[remain[cur]] = -1;
}
}
}
void enumopr(int cur)
{
if (cur == 1) split();
if (cur == 3) {
if (checkrange()) {
remain.clear();
for (int i = 0; i < sigma; i++) {
if (to[i] == -1 && ineql[i]) {
remain.push_back(i);
}
}
dfs(0);
}
return;
}
for (int i = 0; i < sigma; i++) {
if (cur == 0 && !okeql[i]) continue;
if (to[i] == -1 && !fst[i] && !end[i]) {
to[i] = cur;
enumopr(cur + 1);
to[i] = -1;
}
}
}
void solve()
{
memset(to, -1, sizeof(to));
enumopr(0);
for (int i = 0; i < sigma; i++) {
if (ban[i]) continue;
int cert = -1;
bool flag = true;
for (int j = 0; j < sigma; j++) {
if (res[i][j] > 0) {
if (cert == -1) cert = j;
else flag = false;
}
}
if (cert != -1 && flag) {
printf("%c%c\n", 'a' + i, uti[cert]);
}
}
if (nosol) puts("noway");
}
int main()
{
//#ifndef ONLINE_JUDGE
freopen("equation.in", "r", stdin);
freopen("equation.out", "w", stdout);
//#endif
input();
prepare();
solve();
//#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
//#endif
return 0;
}