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的要特判。。
代码:
CF comments里发现一个酷炫的解法,用复数,这样就避免了log在实数定义域不能log负数的问题了
代码:
给定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; }