您的位置:首页 > 其它

Codeforces Round #341 (Div. 2) D. Rat Kwesh and Cheese(数学 | 复数)

2016-02-01 15:02 489 查看
题意:

给定0.1≤x,y,z≤200.0,给出12种x,y,z的幂组合

找到最大的那个,相同输出字典序最小的

分析:

取2次log,分两种情况

一种是x,y,z至少有1个大于1,显然只有大于1的可以做底数,然后比大

一种是x,y,z全都小于等于1,把其中一个取倒数,然后变成了1xyz,然后比分母比小

x,y,z有等于1的要特判。。

代码:

//
//  Created by TaoSama on 2016-02-01
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <complex>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;

double tx, ty, tz;
long double x, y, z, a[15], e[15];
char s[][10] = {"", "x^y^z", "x^z^y", "(x^y)^z", "(x^z)^y", "y^x^z", "y^z^x",
"(y^x)^z", "(y^z)^x", "z^x^y", "z^y^x", "(z^x)^y", "(z^y)^x"
};

int main() {
#ifdef LOCAL
freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif
ios_base::sync_with_stdio(0);

while(scanf("%lf%lf%lf", &tx, &ty, &tz) == 3) {
x = tx, y = ty, z = tz;
e[1] = z * log(y);
e[2] = y * log(z);
e[3] = e[4] = log(y * z);
e[5] = z * log(x);
e[6] = x * log(z);
e[7] = e[8] = log(x * z);
e[9] = y * log(x);
e[10] = x * log(y);
e[11] = e[12] = log(x * y);

for(int i = 1; i <= 4; ++i) a[i] = log(x);
for(int i = 5; i <= 8; ++i) a[i] = log(y);
for(int i = 9; i <= 12; ++i) a[i] = log(z);

bool greaterOne = x > 1 || y > 1 || z > 1;
int ans = -1;
if(greaterOne) {
//find the first >1
for(int i = 1; i <= 12; ++i) if(a[i] > 0) {ans = i; break;}
for(int i = 1; i <= 12; ++i) {
if(a[i] > 0 && log(a[i]) + e[i] > log(a[ans]) + e[ans] + 1e-8)
ans = i;
}
} else {
ans = 1;
//if there is 1, find the first
for(int i = 1; i <= 12; ++i) if(a[i] == 0) {ans = i; break;}
for(int i = 1; i <= 12; ++i) a[i] = -a[i];
for(int i = 1; i <= 12; ++i) {
if(a[i] > 0 && log(a[i]) + e[i] < log(a[ans]) + e[ans] - 1e-8)
ans = i;
}
}
puts(s[ans]);
}
return 0;
}


CF comments里发现一个酷炫的解法,用复数,这样就避免了log在实数定义域不能log负数的问题了



代码:

#include <iostream>
#include <complex>
#include <string>

using namespace std;

bool bigger (complex<long double> a, complex<long double> b) {
if (imag(a) == 0 && imag(b) == 0) {
return real(a) > real(b);
} else if (imag(a) == 0 && imag(b) != 0) {
return true;
} else if (imag(a) != 0 && imag(b) == 0) {
return false;
} else if (imag(a) != 0 && imag(b) != 0) {
return real(a) < real(b);
}
}

int main () {
long double ax, ay, az;
cin >> ax >> ay >> az;

complex<long double> x (ax, 0.0L);
complex<long double> y (ay, 0.0L);
complex<long double> z (az, 0.0L);

complex<long double> cmaz (3, 3);
string ans = "xd";

if (bigger(z * log(y) + log(log(x)), cmaz)) {
cmaz = z * log(y) + log(log(x));
ans = "x^y^z";
}
if (bigger(y * log(z) + log(log(x)), cmaz)) {
cmaz = y * log(z) + log(log(x));
ans = "x^z^y";
}
if (bigger(log(y * z) + log(log(x)), cmaz)) {
cmaz = log(y * z) + log(log(x));
ans = "(x^y)^z";
}

if (bigger(z * log(x) + log(log(y)), cmaz)) {
cmaz = z * log(x) + log(log(y));
ans = "y^x^z";
}
if (bigger(x * log(z) + log(log(y)), cmaz)) {
cmaz = x * log(z) + log(log(y));
ans = "y^z^x";
}
if (bigger(log(x * z) + log(log(y)), cmaz)) {
cmaz = log(x * z) + log(log(y));
ans = "(y^x)^z";
}

if (bigger(y * log(x) + log(log(z)), cmaz)) {
cmaz = y * log(x) + log(log(z));
ans = "z^x^y";
}
if (bigger(x * log(y) + log(log(z)), cmaz)) {
cmaz = x * log(y) + log(log(z));
ans = "z^y^x";
}
if (bigger(log(x * y) + log(log(z)), cmaz)) {
cmaz = log(x * y) + log(log(z));
ans = "(z^x)^y";
}

cout << ans << endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数学 复数