2021“MINIEYE杯”中國大學生算法設計超級聯賽(5)


2021“MINIEYE杯”中國大學生算法設計超級聯賽(5)

1003.VC Is All You Need

  • 題意

給你一個k維平面,問你是不是隨意放n個點都能用k-1條線分隔開

  • 思路

emmmm, 思考一下, n > k + 1都是不行的。。

code:

void solve(){
    ll n,k;
    cin >> n >> k;
    if(n > k+1){
        cout << "No" << endl;
    }else cout << "Yes" << endl;
}

1004.Another String

  • 題意

給定n,k和字符串s, 讓你求出從\(1 \to i\)\(i + 1 \to n\)中任意挑選兩個子字符串,要求長度相同,並且着一堆字符串中最多有k個字符不同,問你有多少對這樣的子字符串

  • 思路

暴力+雙指針,求出f[i][j]表示i,j位置為兩字符串的左端點,滿足要求的最大長度,然后雙指針枚舉長度。
在紙上模擬一邊在通過一些推導可以發現每個位置的貢獻是固定的,用差分+兩次前綴和便可計算答案。。

code:

int f[N][N];
char str[N];
int ans[N];

void solve(){
    int n,k;
    cin >> n >> k;
    cin >> (str + 1);
    // 枚舉右端點
    for(int st = 2;st <= n;st ++) {
        int len = 0;
        int dif = 0;
        // 固定左右端點長度,往后雙指針枚舉
        for(int i = 1, j = st;j <= n;j ++,i ++) {
            while(dif <= k) {
                dif += str[i + len] != str[j + len];
                len ++; 
            }
            f[i][j] = min(len - 1, min(j - i, n - j + 1));
            len --;dif -= (str[i] != str[j]);
        }
    }
    memset(ans,0,sizeof ans);

    for(int i = 1;i <= n;i ++) {
        for(int j = i + 1;j <= n;j ++) {
            ans[i] ++;
            ans[i + f[i][j]] --;
            ans[j] -= f[i][j];
            ans[j + 1] += f[i][j];
        }
    }
    for(int i = 1;i <= n;i ++) ans[i] += ans[i - 1];
    for(int i = 1;i <= n;i ++) {
        ans[i] += ans[i - 1];
        if(i != n) cout << ans[i] << endl;
    }
}

1006.Cute Tree

  • 題意

給出一個類三叉樹的構造方法,讓你輸出它能建立的節點個數

  • 思路

按着圖上的代碼打就行了,又不會超時

code:


int a[N];
int tot;

void build(int id,int l,int r) {
    tot ++;
    id = tot;
    if(l == r) {
        return;
    }
    if(r - l + 1 == 1) {
        int mid = l + r >> 1;
        tot += 2;
        return;
    }else {
        int B = l + ceil((r - l + 1) / 3.0) - 1;
        int C = B + r >> 1;
        if(B >= l)
        build(id,l,B);
        if(C >= B + 1)
        build(id,B + 1,C);
        if(r >= C+1);
        build(id,C+1,r);
    }
}

void solve(){
    tot = 0;
    int n;
    cin >> n;
    for(int i = 1;i <= n;i ++) cin >> a[i];
    build(1,1,n);
    cout << tot << endl;
}

1007.Banzhuan

  • 題意

給一個\(n * n * n\)的立方體空間, 你只能用1立方體積的小立方塊去填,小立方體放在一個位置,那么它的價值就是\(x * y^2 * z\), 並且,如果你防止的地方的底部(z軸)為空,那么它會一直往下掉。

  • 思路

what
然后, dddd , 套公式了。。

code:

const ll mod = 1e9 + 7;
ll qpow(ll a, ll b, ll mod){
    ll ans = 1;
    while(b){
        if(b & 1)ans=ans*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return ans;
}
void solve(){
    ll n;
    cin >> n;
    n %= mod;
    ll res = (n%mod*(n+1)%mod*qpow(2,mod-2,mod)%mod)%mod;
    // cnt計算側面的立方體
    ll cnt = (res%mod*(n%mod*(n+1)%mod*(2*n+1)%mod*qpow(6,mod-2,mod)%mod-1+mod)%mod)%mod;
    // cnt1計算正面
    ll cnt1 = (res%mod-1+mod)%mod*(res%mod)%mod;
    // cnt2底面
    ll cnt2 = ((res%mod)%mod*(n%mod*(n+1)%mod*(2*n+1)%mod)%mod*qpow(6,mod-2,mod)%mod)%mod;
    ll ans = (cnt+cnt1+cnt2 - (res-1+mod)%mod - ((n%mod*(n+1)%mod*(2*n+1)%mod*qpow(6,mod-2,mod)%mod-1+mod)+1ll*2*mod)%mod+ 1ll*5*mod)%mod;//最小值
    ll ans1 =  (n%mod*n%mod*cnt2%mod)%mod; // 最大值
    cout << ans << endl;
    cout << ans1 << endl;
}

1009.Array

  • 題意

給出一個長度為n的序列,滿足一對(l,r)及(\(a_l,a_{l+1}···,a_r\))之中,眾數出現的次數嚴格大於其他非眾數出現的次數

  • 思路

寫了半天的線段樹瘋狂t,給出的數據倒是能過,我人已傻,占坑

code:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM