2018浙江省大学生程序设计竞赛

2018浙江省大学生程序设计竞赛

在这里插入图片描述
saber保佑!

A - Peak

题意:给出一个整数序列,判断序列是否有且仅有一个峰值;

思路:

首先遍历寻找同时严格大于两边元素的值,若存在多个直接pass;

然后分别判断唯一的峰值是否前面递增,后面递减即可;

AC code:

void solve() {
    int n; cin >> n;
    vector<int> a(n);
    for (int i = 0; i< n; i ++) cin >> a[i];
    int cnt = 0;
    int pos = -1;
    for (int i = 1; i < n - 1; i ++) {
        if (a[i] > a[i - 1] && a[i] > a[i + 1]) {
            if (pos == -1) pos = i;
            else {
                cout << "No" << endl;
                return;
            }
        }
    }
    if (pos == -1) {
        cout << "No" << endl;
        return;
    }
    for (int i = 0; i < pos; i ++) {
        if (a[i] >= a[i + 1]) {
            cout << "No" << endl;
            return;
        }
    }
    for (int i = pos; i < n - 1; i ++) {
        if (a[i] <= a[i +1]) {
            cout << "No" << endl;
            return;
        }
    }
    cout << "Yes" << endl;
}

B - King of Karaoke

题意:给出两个整数序列a和b,给序列a的每个元素+k,使得序列a等于序列b的数量最多;

思路:用序列b减去序列a,统计差值的众数即为答案;

AC code:

void solve() {
    cin >> n; 
    for (int i = 1; i <= n; i ++) cin >> a[i];
    for (int i = 1; i <= n; i ++) cin >> b[i];
    map<int, int> mp;
    int ans = 0;
    for (int i = 1; i <= n; i ++) {
        mp[b[i] - a[i]] ++;
        ans = max(ans, mp[b[i] - a[i]]);
    }
    cout << ans << endl;
}

I - Magic Points

题意:有0到n-1共n个点构成的正方环型点集,每两点可以构成一条直线,构造n条直线,使得直线的交点最多;

思路:guess;

从0点开始,n条线的两端点分别为i和i+n进行构造;

但是,对于n为偶数时,最后一条线会与其他线产生的交点二次重合,非最佳情况;

所以偶数情况下最后一条线应该从n-1的点连接(3*(n-1) -1)这个点,最大话交点数;

详情可画图证明,注意,用绘图工具,防止误差;

AC code:

void solve() {
    int n; cin >> n;
    if (n == 2) {
        cout << 0 << ' ' << 2 << ' ' << 1 << ' ' << 3 << endl;
        return;
    }
    if (n & 1) {
        cout << 0 << ' ' << n;
        for (int i = 1; i < n; i ++) cout << ' ' << i << ' ' << i + n;
        cout << endl;
    } else {
        cout << 0 << ' ' << n;
        for (int i = 1; i < n - 1; i ++) cout << ' ' << i << ' ' << i + n;
        cout << ' ' << n - 1 << ' ' << (3 * (n - 1)) - 1;
        cout << endl;
    }
}

J - CONTINUE…?

题意:

将n名学生分成四组G1G2G3G4,第i名学生的价值为i(该价值仅为题目计算描述,无实际意义,每个人都是无价的);

男生只能在G1G2组,女生只能在G3G4组;G1G3组的价值和要等于G2G4的价值和;

给出分配序列,如果不可能,输出-1;

思路:

首先如果所有人的价值和为奇数,则一定不可能成功分组;

可以证明只要是偶数就能成功分配,我们标记sum/2的价值和所在人;

然后开始遍历,被标记的人在G1G3组,否则在G2G4组,再根据男女分;

AC code:

void solve() {
    int n; cin >> n;
    string s; cin >> s;
    s = ' ' + s;
    int sum = n * (n + 1) / 2;
    if (sum & 1) {
        cout << "-1" << endl;
        return;
    }
    sum /= 2;
    vector<int> pos(n + 1, 0);
    for (int i = n; i >= 1; i --) {
        if (sum - i >= 0) {
            sum -= i;
            pos[i] = 1;
        }
    }
    string ans = "";
    for (int i = 1; i <= n; i ++) {
        if (pos[i]) {
            if (s[i] == '1') ans += '3';
            else ans += '1';
        } else {
            if (s[i] == '1') ans += '4';
            else ans += '2';
        }
    }
    cout << ans << endl;
}

K - Mahjong Sorting

题意:略(ε=(´ο`*)))唉);

思路:大模拟,模拟方式很重要,二维拆开模拟+思路混乱WA麻了;

  • 首先,将二维的麻将+点数转换为一维的:
    • 牌为C,点数为x,记录为x;
    • 牌为B,点数为x,记录为x+m;
    • 牌为D,点数为x,记录为x+2*m;
  • 如果当前手牌只有1,则所有的3*m的牌都可能为幸运牌, 优先级1;
  • 现在给出的序列按照题目要求应该为一个递增序列,然后我们开始寻找是否存在空白牌:
  • 不存在空白牌,则当前手牌第一张以及非手牌的3*m-n张牌都可能为幸运牌,优先级3;
  • 特殊,如果当前第二张手牌不为空白牌,且第一张手牌大于第二张手牌,则说明第一张手牌必然是幸运牌,答案为1,优先级2;
  • 其余的,根据空白牌的位置计算区间可能的幸运牌数即可,优先级4;
  • 特判优先级很重要!!!;

AC code:

void solve() {
    int n, m; cin >> n >> m;
    int pos = -1;
    vector<int> a;
    for (int i = 0; i < n; i ++) {
        char c; cin >> c;
        if (c == 'W') {
            pos = i;
            a.push_back(-1);
            continue;
        }
        int x; cin >> x;
        if (c == 'C') a.push_back(x);
        else if (c == 'B') a.push_back(x + m);
        else a.push_back(x + 2 * m);
    }
    a.push_back(3*m+1);
    if (n == 1) {
        cout << 3 * m << endl;
        return;
    }
    if (pos != 1 && a[0] >= a[1]) {
        cout << 1 << endl;
        return;
    }
    if (pos == -1) {
        cout << 3 * m - n + 1 << endl;
        return;
    }
    int ans = 0;
    if (pos == 0) ans += a[1];
    else if (pos == 1) ans += a[2] - a[0];
    else ans += a[pos + 1] - a[pos - 1] - 1;
    cout << ans << endl;
}

L - Doki Doki Literature Club

题意:给出n个字符串单词以及对于每个单词的喜爱度,选出m个单词组成喜爱度最大且字典序最小的字符串排列;

思路:pair存一下,优先喜爱度大排列,次字典序小排列,取前m个输出即可;

AC code:

bool cmp (pair<int, string> a, pair<int, string> b) {
    if (a.first == b.first) return a.second < b.second;
    return a.first > b.first;
}

void solve() {
    int n, m; cin >> n >> m;
    vector<pair<int, string>> a(n);
    for (int i = 0; i < n; i ++) {
        cin >> a[i].second >> a[i].first;
    }
    sort(a.begin(), a.end(), cmp);
    vector<string> ans;
    int cnt = 0;
    for (int i = 0; i < m; i ++) {
        auto [x, s] = a[i];
        cnt += (m - i) * x;
        ans.push_back(s);
    }
    cout << cnt << ' ';
    cout << ans[0];
    for (int i = 1; i < m; i ++) cout << ' ' << ans[i];
    cout << endl;
}

M - Lucky 7

题意:给出长度为n的序列,是否存在元素x+b为7的倍数;

思路:根据题意跑一遍即可;

AC code:

void solve() {
    int n; cin >> n;
    vector<int> a(n);
    int b; cin >> b;
    for (int i = 0; i < n; i ++) cin >> a[i];
    for (int i = 0; i < n; i ++) {
        int x = a[i];
        if ((x + b) % 7 == 0) {
            cout << "Yes" << endl;
            return;
        } 
    }
    cout << "No" << endl;
}
  • 13
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值