SDUT 2021 Winter Individual Contest – G

这次题拿的是2019 ICPC Mid-Central Regional,A、I、L签到模拟,F最短路,C二分答案,H技巧+桶计数,其中L题读错wa了好几发,浪费不少时间,F题经典错误,数组开小又RE2发,还有诸如int溢出,TLE之类的错误。

题目链接

A – Basketball One-on-One

题意

给你一串字符串,A后面的数字代表A得分,B后面的数字代表B得分,问最后谁得分多

题目分析

暴力

代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 1e5+10;
const double PI = acos(-1.0);
typedef pair<int,int> PII;

int main(int argc, char const *argv[]) {
    string s;
    cin >> s;
    int a = 0, b = 0;
    for(int i = 0; i < s.size() - 1; i++) {
        if(s[i] == 'A') a += s[i+1] - '0';
        else if(s[i] == 'B') b += s[i+1] - '0';
    }
    if(a >b) puts("A");
    else puts("B");
    return 0;
}

C – Convoy (二分答案)

题意

一辆车连司机可以坐5人,告诉你每个人开车从A到B或者从B到A花费的时间,一共有k辆车,问你让所有人从A到B花费的最少时间。车最终可以留在A地也可以留在B地,回程司机不能带人。

题目分析

将每个人花费的时间从小到大排,然后二分答案,check时枚举使用的车数,每辆车从小到大分配给每位司机,由于check时假设已经知道花费时间了,所以可以求出每个司机最终连自己可以运送几人,和总人数比较,如果多于总人数则check左边,否则check右边。

代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 1e5+10;
const double PI = acos(-1.0);
typedef pair<int,int> PII;

LL dri, a[maxn];
LL n, k;
bool check(LL x) {
    LL cnt = 0;
    for(LL i = 0; i < dri; i++) {
        LL round = x / a[i];
        cnt += (round+1 >> 1);
        if(round == 0) return cnt*4+i >= n;
    }
    return cnt*4+dri >= n;
}

int main(int argc, char const *argv[]) {
    cin >> n >> k;
    dri = min(n,k);
    for(LL i = 0; i < n; i++) scanf("%lld",&a[i]);
    sort(a,a+n);
    LL l = 0, r = 2e11+10;
    while(l < r) {
        LL mid = l + r >> 1;
        if(check(mid)) r = mid;
        else l  = mid+1;
    }
    cout << l << endl;
    return 0;
}

F – Dragon Ball I (最短路)

题意

告诉你七颗龙珠的位置,要你从1号点出发,收集所有的龙珠,总路径最短。

题目分析

由于龙珠只有七颗,所以可以遍历全部的走法,即七颗龙珠的全排列,然后分别求出全部走法的最短路,找最小值即可,最短路可以预先处理好,分别求出1号点为起点的dijkstra最短路以及七颗龙珠为起点的dijkstra最短路。

代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 5e5 + 10;
const double PI = acos(-1.0);
const LL inf = 0x3f3f3f3f3f3f3f3f;
typedef pair<LL, int> PII;

int h[maxn], val[maxn], to[maxn], ne[maxn], idx, zhu[maxn];
LL dis[10][maxn], tot;
bool vis[maxn];
void add(int u, int v, int w) {
    val[idx] = w;
    to[idx] = v;
    ne[idx] = h[u];
    h[u] = idx++;
}

void dijkstra(int sta) {
    priority_queue<PII> q;
    memset(vis, 0, sizeof vis);
    dis[tot][sta] = 0;
    q.push({0, sta});
    while (q.size()) {
        auto now = q.top();
        q.pop();
        int id = now.second;
        if (vis[id] == 1) continue;
        vis[id] = 1;
        for (int i = h[id]; i != -1; i = ne[i]) {
            int j = to[i];
            if (dis[tot][j] > dis[tot][id] + val[i]) {
                dis[tot][j] = dis[tot][id] + val[i];
                q.push({-dis[tot][j],j});
            }
        }
    }
    tot++;
}

int main(int argc, char const *argv[]) {
    memset(h, -1, sizeof h);
    memset(dis, 0x3f, sizeof dis);
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; i++) {
        int x, y, z;
        cin >> x >> y >> z;
        add(x, y, z);
        add(y, x, z);
    }
    dijkstra(1);
    int pai[10] = {1, 2, 3, 4, 5, 6, 7};
    for (int i = 1; i <= 7; i++) {
        cin >> zhu[i];
        dijkstra(zhu[i]);
    }
    LL ans = inf;
    do {
        LL now = dis[0][zhu[pai[0]]];
        now += dis[pai[0]][zhu[pai[1]]];
        now += dis[pai[1]][zhu[pai[2]]];
        now += dis[pai[2]][zhu[pai[3]]];
        now += dis[pai[3]][zhu[pai[4]]];
        now += dis[pai[4]][zhu[pai[5]]];
        now += dis[pai[5]][zhu[pai[6]]];
        ans = min(ans, now);

    } while (next_permutation(pai, pai + 7));
    if (ans < inf)
        cout << ans << endl;
    else
        puts("-1");
    return 0;
}

H – Farming Mars

题意

给你n块土壤的PH值,有m次询问,每次询问下标为L到R的土壤间,PH值相同的最大值是否大于等于(R-L+1)/2+1,大于等于输出usable。其中PH值为浮点数,精确到小数点后六位。

题目分析

将PH值都 * 1000000从而转换为int,然后用桶的方式记录预处理出所有区间的最大值并比较,m次询问直接查表即可。这道题一开始用了unordered_map,结果TLE了,说明有数据卡hash构造。

代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 1e4+10;
const double PI = acos(-1.0);
typedef pair<int,int> PII;
int a[maxn];
int tong[14000005];
bool flag[maxn][maxn];
int main(int argc, char const *argv[]) {
    int n, m;
    cin >> n >> m;
    for(int i = 1; i <= n; i++) {
        double x;
        scanf("%lf",&x);
        a[i] = (int) (x*1000000) ;
    }
    for(int i = 1; i <= n; i++) {
        int mmax = -1;
        for(int j = i; j <= n; j++) {
            tong[a[j]]++;
            mmax = max(mmax, tong[a[j]]);
            flag[i][j] = mmax >= ((j-i+1)/2+1);
        }
        for(int j = i; j <= n; j++) tong[a[j]] = 0;
    }
    while(m--) {
        int l, r;
        scanf("%d%d",&l,&r);
        if(flag[l][r]) puts("usable");
        else puts("unusable");
    }
    return 0;
}

I – Soft Passwords

题意

给你S和P,若S和P相等;或者将P的所有大写转换成小写,小写转换成大写后相等;或者P前面插入一个数字后等于S;或者P后面插入一个数字等于S;满足一种情况就输出YES,否则输出NO。

题目分析

模拟即可

代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 1e5+10;
const double PI = acos(-1.0);
typedef pair<int,int> PII;

int main(int argc, char const *argv[]) {
    string s, p;
    cin >>s >> p;
    if(s == p) puts("Yes");
    else if(s.size() == p.size()) {
        for(int i = 0; i < s.size(); i++) {
            if(s[i] >= 'a' && s[i] <= 'z') s[i] -=32;
            else if(s[i] >= 'A' && s[i] <= 'Z') s[i] += 32;
        }
        if(s == p) puts("Yes");
        else puts("No");
    }
    else if(s.size() - p.size() == 1) {
        if(s.substr(0,s.size()-1) == p && s[s.size()-1] >= '0' && s[s.size()-1] <= '9') puts("Yes");
        else if(s.substr(1,s.size()-1) == p && s[0] >= '0' && s[0] <= '9') puts("Yes");
        else puts("No");
    }
    else puts("No");
    return 0;
}

L – Umm Code

题意

给你一串字符串,每个单词用空格分隔开,若一个单词只由’u’或者’m’或者标点符号组成,则属于密文的一部分,找到整个字符串的密文后(只有u和m),七个为一组,将u转换成1,m转换成0,组成七位二进制,其十进制表示就是明文所对应的ASCII码,输出明文

题目分析

模拟即可,注意判断标点。

代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn = 5e5 + 10;
const double PI = acos(-1.0);
typedef pair<int, int> PII;
char s[maxn];

char change(string s) {
    int res = 1, now = 1;
    for (int i = s.size() - 1; i >= 0; i--) {
        if (s[i] == 'u') res += now;
        now *= 2;
    }
    return (char)res;
}

int main(int argc, char const *argv[]) {
    cin.getline(s, maxn);
    int n = strlen(s);
    string ans;
    string code;
    int f = 0;
    for (int i = 0; i < n; i++) {
        if (s[i] ==' ') {
            if (f == 1) {
                code.clear();
                f = 0;
            } else {
                ans += code;
                code.clear();
            }
            continue;
        }
        if ((!((s[i] >= 'a' && s[i] <= 'z') ||(s[i] >= 'A' && s[i] <= 'Z') ||(s[i] >= '0' && s[i] <= '9')))) continue;
        if (s[i] != 'u' && s[i] != 'm')
            f = 1;
        code += s[i];
    }
    if (f == 0 && code.size()) ans += code;
    for (int i = 0; i < ans.size(); i += 7) {
        int res = 0, now = 1;
        for (int j = i+6; j >= i; j--) {
            if (ans[j] == 'u') res += now;
            now *= 2;
        }
        cout << (char) res;
    }
    return 0;
}
暂无评论

发送评论 编辑评论


|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇