暑假第二十八测

题解:

第一题:蓝书上原题,每个蚂蚁相对位置不变,排一遍序;

#include<bits/stdc++.h>
using namespace std;
const int M = 100005, E = 1000000000;
double ans[M], t[M] ;
struct Ant{int p, d;}a[M];
int main(){
    freopen("ant.in","r",stdin);
    freopen("ant.out","w",stdout);
    int L, n;
    scanf("%d%d", &L, &n);
    for(int i = 1; i <= n; i++)scanf("%d", &a[i].p);
    for(int i = 1; i <= n; i++){
        scanf("%d", &a[i].d);
        a[i].d = a[i].d ? 1 : -1;
        t[i] = 1.0*(a[i].p + E * a[i].d);
    }
    sort(t + 1, t + 1 + n);
    int lf = 1, rg = n;
    for(int i = 1; i <= n; i++){
        ans[i] = t[i] < 0 ? E + t[i] : E - (t[i] - L);
    }
    for(int i = 1; i <= n; i++)printf("%.2f ", ans[i]);
    puts("");
    
}
View Code

第二题:原题见二十测Tower,才考过,我竟然忘了,只得了80

#include<bits/stdc++.h>
using namespace std;
const int inf = 1e9;
const int M = 5000 + 10;
#define rt register
int a[M], dp[M], s[M], sum[M];
int main(){
    freopen("flower.in","r",stdin);
    freopen("flower.out","w",stdout);
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)scanf("%d", &a[i]), sum[i] = sum[i - 1] + a[i];
    memset(dp, 127, sizeof(dp));
    memset(s, 127, sizeof(s));
    dp[0] = 0;
    s[0] = 0;
    
    for(int i = 1; i <= n; i++)
        for(int j = 0; j < i; j++){
            if(s[j] <= sum[i] - sum[j]){
                dp[i] = min(dp[i], dp[j] + (i - j - 1));
                if(s[i] > sum[i] - sum[j] && dp[i] == dp[j] + i - j - 1)s[i] = sum[i] - sum[j];
            }
        }
    
    printf("%d
", dp[n]);
}
View Code

第三题:又是原题,二分+差分check

#include<bits/stdc++.h>
using namespace std;
const int M = 100005;
int n, K;
long long T, h[M], cf[M], t[M];
bool check(long long k){
    long long res = T;
    for(int i = 1; i <= n; i++){
        t[i] = h[i] - k; cf[i] = t[i] - t[i - 1];
    }
    long long now = 0;
    for(int i = 1; i <= n; i++){
        now += cf[i];
        if(now < 0){
            res += now;
            cf[min(n + 1, i + K)] += now;
            now = 0;
        }
        if(res < 0)return 0;
    }
    return res >= 0;
}


int main(){
    freopen("watering.in","r",stdin);
    freopen("watering.out","w",stdout);
    scanf("%d%d%I64d", &n, &K, &T);
    long long zx = 0, mt = 1e9 + 10;
    for(int i = 1; i <= n; i++)
        scanf("%I64d", &h[i]),zx = max(zx, h[i]), mt = min(mt, h[i]);
    long long lf = mt, rg = T + zx, ans;
    while(lf <= rg){
        long long mid = (lf + rg) >> 1;
        if(check(mid))ans = mid, lf = mid + 1;
        else rg = mid - 1;
        
    }
    printf("%I64d
", ans);
}
View Code

今天三道原题,十个人AK,我在第二题上死了

原文地址:https://www.cnblogs.com/EdSheeran/p/9559826.html