题目链接

本场比赛还行,就是要提高思考的速度,速度太慢导致排名靠后了,继续加油,早日绿名。

A

#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<set>

using namespace std;

const int N = 100010;

void solve() {
    int a, b;
    cin >> a >> b;
    if (a == 1 && b == 1) {
        cout << 1 << endl;
        cout << a << ' ' << b << endl;
    } else if (a == 2 && b == 2) {
        cout << 2 << endl;
        cout << 1 << ' ' << 0 << endl;
        cout << a << ' ' << b << endl;
    } else if (a == 0 || b == 0) {
        if (a != 1 && b != 1) {
            cout << 2 << endl;
            cout << 1 << ' ' << 1 << endl;
            cout << a << ' ' << b << endl;
        } else {
            cout << 1 << endl;
            cout << a << ' ' << b << endl;
        }
    } else if (__gcd(a,b)!=1) {
        cout << 2 << endl;
        cout << a-1 << ' ' << 1  << endl;
        cout << a << ' ' << b << endl;
    } else {
        cout << 1 << endl;
        cout << a << ' ' << b << endl;
    }
}

int main() {
    int h_h;
    cin>>h_h;
    while(h_h--)solve();
    return 0;
}

这个题可以把我所枚举的情况合并一下就是分为gcd为1和不为1,为1的话没有最大公约数,直接就可以过去,不会经过端点,如果不为1就必须走两步,二在坐标轴的情况叶也一样,因为0和任意数字的gcd为任意数,所以就在第二类,而0和1的gcd为1,在第一类,所以就把所有情况包括了,代码就短很多。

#include<bits/stdc++.h>

using namespace std;

const int N = 100010;

int gcd(int a,int b) {
    return b ? gcd(b, a % b) : a;
}

void solve() {
    int a, b;
    cin >> a >> b;
    if (gcd(a, b) == 1) {
        cout << 1 << endl;
        cout << a << ' ' << b << endl;
    } else {
        cout << 2 << endl;
        cout << 1 << ' ' << b - 1 << endl;
        cout << a << ' ' << b << endl;
    }
}


int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int h_h;
    cin >> h_h;
    while (h_h--)solve();
}

B

这个题比赛的时候感觉已经证明出来了,就是在格子里的符号是加减交替出现,而第二行的则是刚好相反,所以我们要让路径的最小值最大,就要尽可能把大的数放到加号的位置,小的数放到减号的位置即可。

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

using namespace std;

const int N = 100010;

int a[3][N];
int b[N];

void solve() {
    int n;
    cin >> n;
    for (int i = 1; i <= 2 * n - 2; i++)b[i] = i;
    a[1][1] = 2 * n;
    for (int k = 2, i = 1, j = 2 * n - 2; k <= n; k++) {
        if (k % 2 == 0) {
            a[1][k] = b[i++];
            a[2][k - 1] = b[i++];
        } else {
            a[2][k - 1] = b[j--];
            a[1][k] = b[j--];
        }
        //if (i + 1 == j)break;
    }
    a[2][n] = 2 * n - 1;
    for (int i = 1; i <= 2; i++) {
        for (int j = 1; j <= n; j++) {
            cout << a[i][j] << ' ';
        }
        cout << endl;
    }
}

int main() {
    int h_h;
    cin>>h_h;
    while(h_h--)solve();
    return 0;
}

C

看了omemi学长的证明过程懂了,就是奇数的位置都可以通过操作加到最后一个奇数的位置上,偶数位置上的数可以加到最后一个位置上,但是我们要注意,奇数的时候,最后一个是奇数,倒数第二个是偶数位置,如果偶数位置上的数小于等于奇数,就符合题意,如果大于的话我们就可以通过不断的将第一个位置的数加到最后一个位置上,因为题目说过可以为负,总可以使偶数位置的数小于等于奇数位置。而偶数的时候,操作完以后就已经固定了,已经无法改变,你想操作最后一个偶数位置变大,那么第一个偶数位置就会变小,就不符合题意了,你想操作最后一个奇数变小,必须使第一个奇数变大,也不符合题意,所以偶数的时候,只有最后一个偶数的位置数大于等于技术位置的数才可以,否则就不行。

#include<bits/stdc++.h>

#define int long long
#define endl '\n';

using namespace std;

const int N = 300010;

int a[N];
int n;

void solve() {
    cin >> n;
    int even = 0, odd = 0;
    for (int i = 1; i <= n; i++) {
        int x;
        cin >> x;
        if (i % 2 == 1)odd += x;
        else even += x;
    }
    if (n % 2 == 1)puts("Yes");
    else {
        if (odd <= even)puts("Yes");
        else puts("No");
    }
}

int32_t  main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    int h_h;
    cin >> h_h;
    while (h_h--)solve();
    return 0;
}