比赛链接

A 被鸽了的课本

签到题

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

int main() {
    int x, y;
    double a;
    cin >> x >> y >> a;
    a = a / 100;
    if ((x + y) * (1 - a) >= x + y * 1.0 / 2)puts("By myself");
    else puts("Through school");
    return 0;
}

B 小L的序列

这个题就是求二进制中01的个数,可以用lowbit也可以直接用短除法,但特别注意的是要去绝对值,还有会爆int要开long long。

#include<bits/stdc++.h>
#define int long long

using namespace std;

bool get(int x) {
    int cnt0 = 0, cnt1 = 0;
    int t;
    while (x) {
        t = x % 2;
        if (t == 1)cnt1++;
        else cnt0++;
        x /= 2;
    }
    if (cnt1 > cnt0)return true;
    else return false;
}

signed main() {
    int n;
    cin >> n;
    int ans = 0;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        if (get(abs(x)))ans++;
        else ans--;
    }
    cout << ans << '\n';
    return 0;
}

C 小Q想撸串

这个题就是用一个数组来存子序列,让目标串和子序列匹配,成功就加到新的字符串,并把子序列往后移一位,最后看看新的字符串与子序列是否相等即可。

#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>

using namespace std;

string s;
string s2="NowCoder";

int main() {
    int T;
    cin >> T;
    while (T--) {
        cin >> s;
        string s1;
        int t = 0;
        for (int i = 0; i < s.size(); i++) {
            if (s2[t] == s[i])s1 += s[i], t++;
        }
        if (s1 == "NowCoder")puts("QAK");
        else puts("QIE");
    }
    return 0;
}

D 兔子的名字

和C题的做法是一样的,比赛时,我以为会超时,但却没有,满分了,最后分析了一下,复杂度是O(nmt[i]),最后的计算量是1e7,低于1e8,稳稳地可以过。

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 1010;

string s[N],str[N];
int n, m;
int a[N];

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i++)cin >> s[i];
    for (int i = 0; i < m; i++)cin >> str[i];
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            string s1;
            int t = 0;
            for (int k = 0; k < s[i].size(); k++) {
                if (str[j][t] == s[i][k])s1 += s[i][k], t++;
            }
            if (s1 == str[j])a[i]++;
        }
    }
    for (int i = 0; i < n; i++)cout << a[i] << endl;
    return 0;
}

E 值周

这个题就是区间合并的裸题,在每次区间中断的时候计算区间内的人数,然后再更新左右端点,最后用总人数减去计算的人数就是剩余的人。

#include<iostream>
#include<cstring>
#include<algorithm>
#define PII pair<int,int>
#define f first
#define s second

using namespace std;

const int N= 1e6 + 10;

PII a[N];
int L, m;

int main() {
    cin >> L >> m;
    for (int i = 0; i < m; i++)cin >> a[i].f >> a[i].s;
    sort(a, a + m);
    int l = a[0].f, r = a[0].s;
    int ans = 0;
    for (int i = 1; i < m; i++) {
        if (a[i].f >= l && a[i].f <= r) {
            r = max(r, a[i].s);
        } else {
            ans += r -l + 1;
            l = a[i].f;
            r = a[i].s;
        }
    }
    ans+=r-l+1;
    cout << L + 1 - ans << endl;
    return 0;
}

我觉得还可以用差分来做,但是最后会有一个答案错误和两个答案超时,我就很懵逼

F zn的手环

这个题就是模拟一下,注意一下时间的细节,最好做的就是把时间全部转化为24小时的形式,在判断一下就可以了。

#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdio>

using namespace std;

int main() {
    int a, b, c, d, e, f;
    char op1, op2;
    scanf("%d:%d %c.m", &a, &b, &op1);//入睡
    scanf("%d:%d %c.m", &c, &d, &op2);//醒来
    scanf("%dh%dmin", &e, &f);
    //printf("%d %d %d %d %d %d %c %c",a,b,c,d,e,f,op1,op2);
    int sum1, sum2;
    if (op1 == 'p')a += 12;
    if (op2 == 'p')c += 12;
    sum1 = a * 60 + b;
    sum2 = c * 60 + d;
    if (sum1 > sum2)sum2 += 1440;
    int h = (sum2 - sum1) / 60;
    int m = (sum2 - sum1) % 60;
    if (h == e && m == f)puts("YES");
    else {
        puts("NO");
        cout << h << "h" << m << "min" << endl;
    }
    return 0;
}

H 兔子的逆序对

这个题的逆序对的数量和逆序数是有一样的性质,交换两个数逆序数和逆序对的奇偶性改变一下,因为是翻转一段区间,而这个区间交换了几次就是区间内的数除以二,最后根据翻转次数判断对应数字的奇偶性就可以了。

#include<iostream>
#include<cstring>
#include<algorithm>

using namespace std;

const int N = 100010;

int n;
int m;
int a[N];

int main() {
    cin >> n;
    int ans = 0;
    for (int i = 0; i < n; i++)cin >> a[i];
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            if (a[i] > a[j])ans++;
        }
    }
    cin >> m;
    for (int i = 1; i <= m; i++) {
        int l, r;
        scanf("%d%d", &l, &r);
        int dis = r - l + 1;
        if (ans & 1) {
            if ((dis / 2) & 1)puts("like"), ans++;
            else puts("dislike");
        } else {
            if ((dis / 2) & 1)puts("dislike"), ans++;
            else puts("like");
        }
    }
    return 0;
}