201612 CSP认证 | 中间数 工资计算 权限查询

1. 中间数

#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int a[N];
int main()
{
    int n;  scanf("%d", &n);
    int x;
    for(int i = 0;i < n;i ++){
        scanf("%d", &x);
        a[x] ++;
    }
    
    int cnt = 0;  //cnt 用来记录比当前值小的数的个数
    for(int i = 1;i <= 1000;i ++){
        if(a[i]){
            int less = cnt, greater = n - less - a[i];
            if(less == greater){
                cout << i;
                return 0;
            }
            cnt += a[i];
        }
    }
    cout << -1;
    return 0;
}

2. 工资计算

#include<bits/stdc++.h>
using namespace std;
int tax[] = {45, 300, 900, 6500, 6000, 8750};
int gap[] = {1500, 4500, 9000, 35000, 55000, 80000};
float rate[] = {0.97, 0.9, 0.8, 0.75, 0.7, 0.65, 0.55};
int main()
{
    int t; cin >> t;
    
    if(t <= 3500){
        cout << t; 
        return 0;
    }
    t -= 3500;
    
    int pos = 0; bool flag = false;
    while(!flag){
        if(pos > 5){
            //大于80000
            flag = true;
            t += (float(t - 80000) / rate[pos] * (1 - rate[pos]));
        }
        //要么直接大于,要么减去前一个分段,用在当前分段的钱除以比例得到当前分段的原始钱加上前一个分段的值,如果此时大于当前划分也是满足条件的
        //比如1530,减去45减去3后小于1500,但是原始仍然是大于1500减了45的,得用最满的计算当前区间
        if(t >= gap[pos] || float(t - gap[pos - 1]) / rate[pos] + gap[pos - 1] >= gap[pos]){
            t += tax[pos];
            pos ++;
        }
        else {
            //此时已经到达分阶段纳税的最后一个级别
            //先减去上一个分段数目,剩下的是占全部的百分之rate[pos].得到总数目后乘税率
            t += (float(t - gap[pos - 1]) / rate[pos] * (1 - rate[pos]));
            flag = true;
        }
    }
    cout << t + 3500;
    return 0;
}

3. 权限查询
男默女泪了,我居然也可以独立的写出第三题的
虽然是久远的2016年,老天爷嘞

#include<bits/stdc++.h>
using namespace std;

int p, r, u, q;

unordered_map<string, int> permission;
unordered_map<string, set<string> >role_perName;  //用来记录每个角色具有哪些权限
unordered_map<string, int> role_perGrade;  //记录角色名_权限名:也即该角色具有的权限等级
unordered_map<string, set<string> >user_perName;  //用来记录每个用户具有哪些权限
unordered_map<string, int> user_perGrade; //记录用户名_权限名:也即该用户具有的权限等级

void Permission(string line)
{
    int len = line.size();
    string key;
	
	//分离出权限名字和等级,其中无等级的默认为10(等级限定为0-9)
    if(line[len - 2] == ':'){  //有等级权限
        key = line.substr(0, line.size() - 2);
        permission[key] = line[len - 1] - '0';
    }
    else {
        key = line;
        permission[key] = 10;
    }
}

void Role()
{
    string role_name, line, per_name;
    int cnt, grade;

    cin >> role_name;
    scanf("%d", &cnt);

    while(cnt --){
        cin >> line;
        int len = line.size();
        if(line[len - 2] == ':'){
            per_name = line.substr(0, line.size() - 2);  //提取权限名
            grade = line[len - 1] - '0';  //提取当前权限的等级
        }
        else {
            per_name = line;
            grade = 10;
        }

        role_perName[role_name].insert(per_name);

        string key = role_name + '_' + per_name;  //做一个字符串的拼接用作role_perGrade的key,也就是同时用角色名字和权限名字做索引
        if(role_perGrade.count(key)){
            //曾经出现过该权限,权限取最大值
            role_perGrade[key] = max(role_perGrade[key], grade);
        }
        else{  //该角色第一次出现该权限
            role_perGrade[key] = grade;
        }
    }
}

void User()
{
    string user_name, role_name, line;
    int cnt;

    cin >> user_name;
    scanf("%d", &cnt);

    while(cnt --){
        cin >> role_name;
        set<string> permission_set = role_perName[role_name];  //取出当前角色对应的权限集合
        for(auto x : permission_set){
            user_perName[user_name].insert(x);  //当前用户具有权限x

            string key_role_per = role_name + '_' + x;
            string key_user_per = user_name + '_' + x;  //定义新字符为用户名_权限名,也即二级名称作为新的索引

            int grade = role_perGrade[key_role_per];

            if(user_perGrade.count(key_user_per)){
                //如果之前该用户已经拥有该权限,取最大
                user_perGrade[key_user_per] = max(user_perGrade[key_user_per], grade);
            }
            else {
                user_perGrade[key_user_per] = grade;
            }

        }
    }
}

//user是否具有权限per
void handle(string user_name, string per)
{
    int len = per.size(), grade;
    string per_name;
    bool flag = false;  //是否有冒号,区分不同查询

    if(per[len - 2] == ':'){  //有等级权限
        per_name = per.substr(0, per.size() - 2);
        flag = true;
        grade = per[len - 1] - '0';
    }
    else {
        per_name = per;
    }

    string key = user_name + '_' + per_name;

    if(user_perGrade.count(key)){  //如果该用户存在该权限
        if(flag){  //比较该等级是否合法
            if(grade <= user_perGrade[key]){
                cout << "true" << endl;
            }
            else cout << "false" << endl;
        }
        else{  //没有冒号,可能为无等级权限(此时需要返回是否具有该权限)或者查询(此时需要返回该用户具有该权限的等级)
            grade = user_perGrade[key];
            if(grade == 10) cout << "true" << endl;
            else cout << grade << endl;
        }
    }
    else {
        cout << "false" << endl;
    }
}

int main()
{
    cin >> p;
    string line;
    getline(cin, line);

    for(int i = 0;i < p;i ++){
        getline(cin, line);
        Permission(line);
    }
    /*
    for(auto it : permission){
        cout << it.first << " "<<it.second << endl;
    }*/

    cin >> r;
    for(int i = 0;i < r;i ++){
        Role();
    }

    cin >> u;
    for(int i = 0;i < u;i ++){
        User();
    }

    cin >> q;
    string user_name, per;
    while(q --){
        cin >> user_name >> per;
        handle(user_name, per);
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值