1. 程式人生 > >2011 noip 提高組

2011 noip 提高組

首先吐槽:剛剛寫著寫著突然藍屏了,,emmm,寫到最後一題了藍屏了、

當時我的內心是崩潰的。

然後,旁邊的大佬默默來了一句:論儲存草稿的重要性。

連著藍了三次之後開了防火牆,然後,,我左邊那位同學又開始藍屏了。。

Day 1

T1  鋪地毯

 判斷條件是

x >= a[i] &&x <= a[i] + g[i] && y >= b[i] && y <= b[i] + k[i]

#include <cstdio>
int n, a[10000], b[10000], g[10000], k[10000
], t, x, y; int main() { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d%d%d%d", &a[i], &b[i], &g[i], &k[i]); scanf("%d%d", &x, &y); for(int i = 1; i <= n; i++) if(x >= a[i] &&x <= a[i] + g[i] && y >= b[i] && y <= b[i] + k[i]) t
= i; t == 0 ? printf("-1") : printf("%d", t); return 0; }

 T2 選擇客棧

 

把三重迴圈的暴力優化成一層。

#include <cstdio>
#include <iostream> 
#define in inline
#define is isdigit
using namespace std;
in int read() {
    int X = 0, w = 0;
    char ch = 0;
    while(!is(ch)) {
        w 
|= ch == '-'; ch = getchar(); } while(is(ch)) { X = (X << 3) + (X << 1) + (ch ^ 48); ch = getchar(); } return w ? -X : X; } void print(int x) { if(x < 0) putchar('-'), x = -x; if(x > 9) print(x / 10); putchar(x % 10 + '0'); } int n, k, p, m, sum, num, ans, a[20010], b[20010], c[20000]; int main() { n = read(); k = read(); p = read(); for(int i = 1; i <= n; i++) { num = read(); sum = read(); if(sum <= p) m = i; if(m >= a[num]) c[num] = b[num]; a[num] = i; ans += c[num]; b[num]++; } print(ans); return 0; }

T3 Mayan遊戲

 

大模擬搜尋題,唔,,,我的程式碼會被hack,,雖然A了。

這裡參照一位大佬的做法->https://www.luogu.org/blog/sumijie/solution-p1312

 

Day 2 

T1 計算係數

 

大家都用楊輝三角但是我太弱了,,不會

於是,dp

#include <cstdio>
long long f[1005][1005] = {1}, a, b, n, m, k;
int main() {
    scanf("%lld%lld%lld%lld%lld", &a, &b, &k, &n, &m);
    for(int i = 0; i <= n; i++)
        for(int j = 0; j <= m; j++) {
            if(i) f[i][j] = (f[i][j] + f[i - 1][j] * a) % 10007;
            if(j) f[i][j] = (f[i][j] + f[i][j - 1] * b) % 10007;
        }
    printf("%lld", f[n][m]);
    return 0;
}

T2 聰明的質檢員

 

非常經典的二分題目,出去學習老師們應該都會講

#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
int w[200001], v[200001], l[200001], r[200001], m, n, ll, rr = 1000000;
long long sumw[200001], sumv[200001], s, ansn = 10000000000000000LL;
long long ok(int mid) {
    long long ret = 0;
    for(int i = 1; i <= n; ++i) 
        if(w[i] >= mid) sumw[i] = sumw[i - 1] + 1, sumv[i] = sumv[i - 1] + v[i];
        else sumw[i] = sumw[i - 1], sumv[i] = sumv[i - 1];
    for(int i = 1; i <= m; ++i)
        ret += (sumw[r[i]] - sumw[l[i] - 1]) * (sumv[r[i]] - sumv[l[i] - 1]);
    return ret;
}
int main() {
    scanf("%d%d%lld", &n, &m, &s);
    for(int i = 1; i <= n; ++i) scanf("%d%d", &w[i], &v[i]);
    for(int i = 1; i <= m; ++i) scanf("%d%d", &l[i], &r[i]);
    while(ll < rr) {
        int mid = (ll + rr) / 2 + 1;
        long long tmp = ok(mid) - s;
        ansn = min(ansn, abs(tmp));
        if(tmp > 0) ll = mid;
        else if(tmp < 0) rr = mid - 1;
        else {
            ansn = 0; break;
        }
    }
    printf("%lld", ansn);
} 

T3 觀光公交

 

貪心的經典題目

#include <cstdio>
#include <iostream>
using namespace std;
#define MAXN 10100
int p, temp, ans, n, m, k, d[MAXN], t[MAXN], a[MAXN], b[MAXN], num[MAXN], vis[MAXN], dis[MAXN], sum[MAXN];
int main() {
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i < n; i++) 
        scanf("%d", &d[i]);
    for(int i = 1; i <= m; i++) 
        scanf("%d%d%d", &t[i], &a[i], &b[i]);
    for(int i = 1; i <= m; i++) 
        num[b[i]]++, vis[a[i]] = max(vis[a[i]], t[i]);
    for(int i = 2; i <= n; i++) 
        dis[i] = max(dis[i - 1], vis[i - 1]) + d[i - 1];
    for(int i = 1; i <= m; i++) 
        ans += dis[b[i]] - t[i];
    while(k--) {
        p = temp = -1;
        for(int i = n - 1; i; i--) {
            dis[i + 1] <= vis[i + 1] ? sum[i] = num[i + 1] : sum[i] = sum[i + 1] + num[i + 1];
            if(sum[i] > temp && d[i]) temp = sum[i], p = i;
        }
        if(p == -1) break;
        ans -= temp, d[p]--;
        for(int i = p + 1; i <= n; i++) 
            dis[i] = max(dis[i - 1], vis[i - 1]) + d[i - 1];
    }
    printf("%d", ans);
    return 0;
}

一世安寧