ZOJ-3704 I am Nexus Master! 模拟

题意:有一个判定用户等级的系统,现在不同的等级有不同的评价标准,现给定一个用户的历史等级以及当前最新的数据,要求给出目前的等级。

解法:把不同的等级标题映射到数字,然后或者历史等级的标号,然后从大的往当前标号枚举,查看是否升级,如果升级则推出判定;否则从当前等级往小的标号枚举,查看是否降级,查看降级时只需要判定比率是否小于一个阀值即可,因为其他满足历史等级的条件一定满足标号比它小的等级,遇到不降级即退出判定。由于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;    
}

 

posted @ 2013-05-08 20:58  沐阳  阅读(605)  评论(3编辑  收藏  举报