题意:有一个判定用户等级的系统,现在不同的等级有不同的评价标准,现给定一个用户的历史等级以及当前最新的数据,要求给出目前的等级。
解法:把不同的等级标题映射到数字,然后或者历史等级的标号,然后从大的往当前标号枚举,查看是否升级,如果升级则推出判定;否则从当前等级往小的标号枚举,查看是否降级,查看降级时只需要判定比率是否小于一个阀值即可,因为其他满足历史等级的条件一定满足标号比它小的等级,遇到不降级即退出判定。由于Peasant的判定于其他不太一样,在开始的时候就判定一下。
代码如下:
#include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <map> #include <string> using namespace std; const double eps = 1e-8; struct User { char title[20]; int weeks; double down, up, ratio; void read() { scanf("%s %d %lf %lf", title, &weeks, &down, &up); ratio = up / down; } void show() { puts(title); } void modify(); }u; int wk[10] = {0, 0, 4, 8, 15, 25, 40, 60, 80, 100}; int dn[10] = {0, 0, 50, 120, 300, 500, 750, 1024, 1536, 3072}; double ru[10] = {0, 0, 1.05, 1.55, 2.05, 2.55, 3.05, 3.55, 4.05, 4.55}; double rd[10] = {0, 0, 0.95, 1.45, 1.95, 2.45, 2.95, 3.45, 3.95, 4.45}; string str[10] = { "Peasant", "User", "Power_User", "Elite_User", "Crazy_User", "Insane_User", "Veteran_User", "Extreme_User", "Ultimate_User", "Nexus_Master" }; map<string, int>mp; int init() { for (int i = 0; i < 10; ++i) { mp[str[i]] = i; } } int sign(double x, double y) { if (x - y > eps) return 1; else if (y - x > eps) return -1; else return 0; } bool judge_peasant() { if (sign(u.down, 50) >= 0 && sign(u.ratio, 0.4) < 0) return true; if (sign(u.down, 100) >= 0 && sign(u.ratio, 0.5) < 0) return true; if (sign(u.down, 200) >= 0 && sign(u.ratio, 0.6) < 0) return true; if (sign(u.down, 400) >= 0 && sign(u.ratio, 0.7) < 0) return true; if (sign(u.down, 800) >= 0 && sign(u.ratio, 0.8) < 0) return true; return false; } bool upclass(int x) { if (u.weeks >= wk[x] && sign(u.down, dn[x]) >= 0 && sign(u.ratio, ru[x]) >= 0) return true; return false; } bool dnclass(int x) { if (sign(u.ratio, rd[x]) < 0) return true; return false; } void User::modify() { if (judge_peasant()) { strcpy(title, str[0].c_str()); return; } int rank = mp[title]; // 获得当前的排名 for (int i = 9; i > rank; --i) { // 首先判定是否得到了更高的等级 if (upclass(i)) { strcpy(title, str[i].c_str()); return; } } for (int i = rank; i > 1; --i) { if (!dnclass(i)) { // 如果能够保住这个等级则退出判定 return; } else { // 否则下降一个等级 strcpy(title, str[i-1].c_str()); } } } /* 3 Crazy_User 5000 5000 50000000 Crazy_User 15 800.00 639.99 Veteran_User 45 1000.00 3000.00 Insane_User 45 1000.00 3000.00 */ int main() { int T; init(); for (scanf("%d", &T); T; T--) { u.read(), u.modify(), u.show(); } return 0; }