1. 程式人生 > 其它 >SZUACM2022招新積分賽Day2 總結

SZUACM2022招新積分賽Day2 總結

SZUACM2022招新積分賽Day2 總結

很難過但還是來補題
這次給一些題目添上了圖解

題目

下午

晚上

補題

A. 51Nod 1001

簽到題,卻WA了三次。。
直接i j 兩頭找就行了

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

using namespace std;
const int N = 50005;
int n, k;
int a[N];

signed main () {
    cin >> k >> n;
    for (int i = 1; i <= n; i ++)
        cin >> a[i];

    sort (a + 1, a + n + 1);
    bool flag = false;

    for (int i = 1, j = n; i < j; ) {
        if (a[i] + a[j] == k) {
            flag = true;
            cout << a[i] << ' ' << a[j] << endl;
            i ++, j --;
        }
        if (a[i] + a[j] < k)
            i ++;
        if (a[i] + a[j] > k)
            j --;
        
    }

    if (!flag)
        cout << "No Solution" << endl;
}
//-4 -3 -2 -1  

B.51Nod - 1105

二分

注意細節,詳見程式碼註釋

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N = 50005;

ll a[N], b[N];
int n, k;

int check (ll x) {
    int cnt = 0, j = n;
    for (int i = 1; i <= n; i ++) {
        while (a[i] * b[j] > x)
            j --;
        cnt += n - j; //因為最後再減了一次,所以免去那個+1
    }
    return cnt;
}

int main () {
    scanf ("%d%d", &n, &k);
    for (int i = 1; i <= n; i ++)
        scanf ("%lld%lld", &a[i], &b[i]);

    sort (a + 1, a + n + 1);
    sort (b + 1, b + n + 1);

    ll l = a[1] * b[1], r = a[n] * b[n];
    while (l < r) {
        ll mid = l + r >> 1;
        if (check (mid) < k)
            r = mid;
        else
            l = mid + 1;

    }
    printf ("%lld", r);
}
//。。。就是二分

//再優化:固定一個,列舉另一個
//若滿足,則中間一整段都滿足
//畫個圖

//若a[i]*b[j]>x,則b[j]之後所有b[i]也必定滿足a[i]*b[j]
//長度為n-j+1(因為j在往回跳,所以最終為n-j)

E. Gym 102992K
構造,由重要性質\(gcd(i, i+1)=1\)可以想到整體偏移來構造。
具體如下:

得Code:

#include <bits/stdc++.h>

using namespace std;
const int N = 1e6 + 5;
int n, k;

int main () {
    cin >> n >> k;
    if (k == 0 ) {
        cout << -1;
        return 0;
    }

    int st = 2;
    for (int i = 1; i <= n; i ++) {
        if (i == k)
            cout << 1;
        else
            cout << st ++;
        if (i != n)
            cout << ' ';
    }

}
//注意一個重要性質gcd(i,i+1)=1
//所以構造方法為把1放在k位置上,
//然後以此為分界線在此之前的前移,後面的不變

//行末不能有空格!!!!!