E- Seven tombs
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 31 Accepted Submission(s) : 9
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
塔.拉夏被埋葬在术士峡谷的七个古墓中的一个。
塔.拉夏的古墓一共有七种不同的符号,分别用A、B、C、D、E、F、G表示。每个古墓中分别封印着一种力量,用1、2、3、4、5、6、7表示。为了防止以后有人取得这些力量,赫拉迪姆将这些对应的关系全部隐藏起来了。
为了获得这七种力量,你终于找到了一点线索:一个古代赫拉迪姆留下的式子。这个式子表示了七种力量对应的关系。经过破译,终于知道将七种符号所表示的力量的代号分别代进式子中,使得等式成立的,就是开启封印的钥匙。
写一个程序解开这个迷题。
塔.拉夏的古墓一共有七种不同的符号,分别用A、B、C、D、E、F、G表示。每个古墓中分别封印着一种力量,用1、2、3、4、5、6、7表示。为了防止以后有人取得这些力量,赫拉迪姆将这些对应的关系全部隐藏起来了。
为了获得这七种力量,你终于找到了一点线索:一个古代赫拉迪姆留下的式子。这个式子表示了七种力量对应的关系。经过破译,终于知道将七种符号所表示的力量的代号分别代进式子中,使得等式成立的,就是开启封印的钥匙。
写一个程序解开这个迷题。
Input
一行一个字符串,为一个只有变量A..G的等式。式子中只含有字母、加、减、乘号以及括号和一个等号,并且“ABC”表示A*100+B*10+C,字符串长度不超过100。
Output
一行,输出对应等式的解。如果有多种可能,输出ABCDEFG表示十进制数最小的一个。输入数据保证有解。
Sample Input
(A+B)*C-E*(C+D)=FF
Sample Output
(2+6)*7-1*(7+5)=44
上面就是题目了
还是用的最原始的方法,麻烦!要学习新方法了!
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;bool over( char l[],char num[] )
{l[strlen(l)]='=';l[strlen(l)+1]=0;char s1[1111];int st1=0;int s2[1111],st2=0;int i;s1[st1++]='(';for( i=0;i<strlen(l);i++ ){if( l[i]=='(' )s1[st1++]=l[i];else if( l[i]=='+' || l[i]=='-' || l[i]=='*' ){if( s1[st1-1]=='*' ){s2[st2-2]=s2[st2-2]*s2[st2-1];st2--;st1--;}s1[st1++]=l[i];}else if( l[i]==')' || l[i]=='=' ){while( s1[st1-1]!='(' ){if( s1[st1-1]=='+' )s2[st2-2]=s2[st2-2]+s2[st2-1];else if( s1[st1-1]=='-' )s2[st2-2]=s2[st2-2]-s2[st2-1];else if( s1[st1-1]=='*' )s2[st2-2]=s2[st2-2]*s2[st2-1];st2--;st1--;}st1--;if( l[i]=='=' )break;}else{if( i-1>=0&&l[i-1]>='0'&&l[i-1]<='9' )s2[st2-1]=s2[st2-1]*10+l[i]-'0';elses2[st2++]=l[i]-'0';}}int left=s2[0];st1=st2=0;s1[st1++]='(';for( i++;i<strlen(l);i++ ){if( l[i]=='(' )s1[st1++]=l[i];else if( l[i]=='+' || l[i]=='-' || l[i]=='*' ){if( s1[st1-1]=='*' ){s2[st2-2]=s2[st2-2]*s2[st2-1];st2--;st1--;}s1[st1++]=l[i];}else if( l[i]==')' || l[i]=='=' ){while( s1[st1-1]!='(' ){if( s1[st1-1]=='+' )s2[st2-2]=s2[st2-2]+s2[st2-1];else if( s1[st1-1]=='-' )s2[st2-2]=s2[st2-2]-s2[st2-1];else if( s1[st1-1]=='*' )s2[st2-2]=s2[st2-2]*s2[st2-1];st2--;st1--;}st1--;if( l[i]=='=' )break;}else{if( i-1>=0&&l[i-1]>='0'&&l[i-1]<='9' )s2[st2-1]=s2[st2-1]*10+l[i]-'0';elses2[st2++]=l[i]-'0';}}int right=s2[0];if( left==right )return true;elsereturn false;
}int main()
{char line[222];while( gets(line) ){char num[8]="1234567";do{char l[222];memset(l,0,sizeof(l));strcpy(l,line);for( int i=0;i<strlen(l);i++ ){if( l[i]=='A' )l[i]=num[0];else if( l[i]=='B' )l[i]=num[1];else if( l[i]=='C' )l[i]=num[2];else if( l[i]=='D' )l[i]=num[3];else if( l[i]=='E' )l[i]=num[4];else if( l[i]=='F' )l[i]=num[5];else if( l[i]=='G' )l[i]=num[6];}if( over(l,num) ){l[strlen(l)-1]=0;printf( "%s\n",l );break;}}while(next_permutation(num,num+7));}return 0;
}
//((((A+B)*C-E*(C+D))))=(FF)
下面是标程 个人觉得写得蛮好的,用递归实现。
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
//ifstream fin("tomb.in");
//ofstream fout("tomb.out");bool valid = true, Found = false;
string buf;
int hash[8], dat[8];int rank[128] = {0};
double num(const char*& e) {int n(0);double x(0.);if (1 == sscanf(e, "%lg%n", &x, &n)) e += n; else valid = false;return x;
}
double calc(double x, char op, double y) {switch (op) {case '+': return (x + y);case '-': return (x - y);case '*': return (x * y);case '/':if (y) return (x / y);else {valid = false;return 0.;}}return 0.;
}
double eval(const char*& e) {double stack[32];char ops[32];int top(0);while (valid && *e && *e != ')') {if ('(' == *e) {++ e;stack[top] = eval(e);if (*e ++ != ')') valid = false;}else stack[top] = num(e);if (!*e || ')' == *e) break;if (rank[*e]) {while (top > 0 && rank[ops[top - 1]] >= rank[*e]) {-- top;stack[top] = calc(stack[top], ops[top], stack[top + 1]);}ops[top ++] = *e ++;}else valid = false;}while (top --) stack[top] = calc(stack[top], ops[top], stack[top + 1]);return (*stack);
}string L, R;
void dfs(int l) {if (Found) return;if (l == 7) {bool flag = 0;int i;L = ""; R = "";for (i = 0; i < buf.length(); i ++) {if (buf[i] == '=') {flag = 1;continue;}if (flag == 0) L += buf[i];else R += buf[i];}for (i = 0; i < L.length(); i ++)if (L[i] >= 'A' && L[i] <= 'Z') L[i] = dat[L[i] - 'A'] + '0';for (i = 0; i < R.length(); i ++)if (R[i] >= 'A' && R[i] <= 'Z') R[i] = dat[R[i] - 'A'] + '0';const char *x = L.c_str();const char *y = R.c_str();if (eval(x) == eval(y)) {cout << L << "=" << R << endl;Found = true;}return;}for (int i = 1; i <= 7; i ++)if (!hash[i]) {hash[i] = true;dat[l] = i;dfs(l + 1);hash[i] = false;}
}
int main (void) {rank['+'] = rank['-'] = 1;rank['*'] = rank['/'] = 2;cin >> buf;dfs(0);return 0;
}