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';
else
s2[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';
else
s2[st2++]=l[i]-'0';
}
}
int right=s2[0];
if( left==right )
return true;
else
return 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;
}