Educational Codeforces Round 89 (Rated for Div. 2)(A, B, C, D)

Educational Codeforces Round 89 (Rated for Div. 2)

A. Shovels and Swords

思路

題意非常簡單,就是得到最多的物品嘛,我們假定a,ba, baa是最小的一個,分兩種情況。

如果2a<=b2 * a <= b,那麼我們只需要購買花費是1,21, 2的東西即可,也就是最後能購買得到aa件物品。

否則的話,我們一定是先讓數量更多的去減22,用數量更少的去減11,直到兩個物品的數量相等,再通過1,21, 22,12, 1的順序去交換執行,總結一下最後的答案就是(n+m)/3(n + m) / 3

代碼

#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef unsigned long long ull;

const double eps = 1e-7;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;

inline ll read() {
    ll f = 1, x = 0;
    char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    } 
    while(c >= '0' && c <= '9') {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }
    return f * x;
}

const int N = 2e5 + 10;

int main() {
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = read();
    while(t--) {
        ll a = read(), b = read();
        if(a > b)   swap(a, b);
        if(a * 2 <= b)  printf("%lld\n", a);
        else    printf("%lld\n", (a + b) / 3);
    }
    return 0;
}

B.Shuffle

思路

就是一個區間有重合判斷並集的問題,如果我們給定的區間[l,r][l, r]在原本的區間外也就是r<Ll>Rr < L || l > R,否則的話我們就更新L,RL, R的最大最小值

代碼

#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef unsigned long long ull;

const double eps = 1e-7;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;

inline ll read() {
    ll f = 1, x = 0;
    char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    } 
    while(c >= '0' && c <= '9') {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }
    return f * x;
}

const int N = 2e5 + 10;

int main() {
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = read();
    while(t--) {
        int n = read(), x = read(), m = read();
        int l = x, r = x;
        // cout << l << " " << r << endl;
        for(int i = 1; i <= m; i++) {
            int a = read(), b = read();
            if((a <= r && a >= l) || (b >= l && b <= r) || (l >= a && b >= r)) {//比賽時判斷條件寫的比較繁瑣。
                l = min(l, a);
                r = max(r, b);
            }
            // cout << l << " " << r << endl;
        }
        printf("%d\n", r - l + 1);
    }
    return 0;
}

C.Palindromic Paths

思路

開兩個數組,num1[i]num1[i]記錄的是步數爲ii的時候的位置上的11的個數,num0[i]num0[i]記錄的是步數爲ii的時候的位置上00的個數,因爲整體的步數就是在[1,n+m1][1, n + m - 1]之間,所以我們可以通過對每一步全變爲00或者全變爲11中挑選一個最小值,作爲我們的花費,然後累加花費就是答案。

代碼

#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef unsigned long long ull;

const double eps = 1e-7;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;

inline ll read() {
    ll f = 1, x = 0;
    char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    } 
    while(c >= '0' && c <= '9') {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }
    return f * x;
}

const int N = 2e5 + 10;

int a[40][40];

int num0[100], num1[100];

int main() {
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = read();
    while(t--) {
        memset(num1, 0, sizeof num1);
        memset(num0, 0, sizeof num0);
        int n = read(), m = read();
        // cout << n << " " << m << endl;
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++) {
                a[i][j] = read();
                if(a[i][j] == 1)    num1[i + j]++;
                else num0[i + j]++;
            }
        if(n == 2 && m == 2) {
            puts("0");
            // puts("");
            continue;
        }
        int ans = 0;
        int l = 2, r = n + m;
        while(l < r) {
            //好像這個if語句並沒有什麼用,不知道比賽的時候怎麼想的。
            if((num1[l] && num0[l]) || (num1[r] && num0[r]) || (num1[l] && num0[r]) || (num0[l] && num1[r]))
                ans += min(num0[l]+ num0[r], num1[l] + num1[r]);
            // cout << ans << "\n";
            l++, r--;
        }
        printf("%d\n", ans);
        // puts("");
    }
    return 0;
}

D.Two Divisors

思路

先引入一個定理gcd(a,b)=1=gcd(a+b,ab)gcd(a, b) = 1 = gcd(a + b, a * b),所以這道題就簡簡單單就可以水過了,但是我的賽況卻不是如此,,,,,

那我們來證明一下這個定理的正確性吧:

假設有KaTeX parse error: Undefined control sequence: \and at position 15: gcd(x, y) = 1 \̲a̲n̲d̲ ̲gcd(x, z) = 1,所以gcd(x,yz)=1gcd(x, y * z) = 1

gcd(a,b)=1>gcd(a+b,b)=1=gcd(a,a+b)>gcd(a+b,ab)=1gcd(a, b) = 1 -> gcd(a + b, b) = 1 = gcd(a, a + b) - > gcd(a + b, a * b) = 1

代碼

#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back

using namespace std;

typedef pair<int, int> pii;
typedef long long ll;
typedef unsigned long long ull;

const double eps = 1e-7;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;

inline ll read() {
    ll f = 1, x = 0;
    char c = getchar();
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    } 
    while(c >= '0' && c <= '9') {
        x = (x << 1) + (x << 3) + (c ^ 48);
        c = getchar();
    }
    return f * x;
}

const int N1 = 1e7 + 10, N2 = 5e5 + 10;

int prime[N1], cnt;
int ans1[N2], ans2[N2], n;
bool st[N1];

int main() {
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    for(int i = 2; i < N1; i++) {
        if(!st[i])  prime[++cnt] = i;
        for(int j = 1; j <= cnt && i * prime[j] < N1; j++) {
            st[i * prime[j]] = true;
            if(i % prime[j] == 0)   break;
        }
    }
    n = read();
    for(int i = 1; i <= n; i++) {
        int temp = read();
        ans1[i] = ans2[i] = -1;
        for(int j = 1; prime[j] * prime[j] <= temp; j++) {
            int x = 1;
            if(temp % prime[j] == 0) {
                while(temp % prime[j] == 0) {
                    temp /= prime[j];
                    x *= prime[j];
                }
                if(temp == 1)   break;
                else {
                    ans1[i] = x;
                    ans2[i] = temp;
                    break;
                }
            }
        }
    }
    for(int i = 1; i <= n; i++)
        printf("%d%c", ans1[i], i == n ? '\n' : ' ');
    for(int i = 1; i <= n; i++)
        printf("%d%c", ans2[i], i == n ? '\n' : ' ');
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章