1. 程式人生 > >noip刷題記錄 20170823

noip刷題記錄 20170823

algo 多維 sizeof truct tdi ini sca c-c str

獨木橋

怎麽說呢

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

const int N = 5050;
int n, l, pos[N], maxx = 0, minn = 0;

int main(){
    scanf("%d%d", &l, &n);
    for(int i = 1; i <= n; i++) scanf("%d", &pos[i]);
    sort(pos + 1, pos + n + 1
); for(int i = 1; i <= n; i++) if(pos[i] <= (1 + l) / 2) maxx = max(maxx, l - pos[i] + 1), minn = max(pos[i], minn); else maxx = max(maxx, pos[i]), minn = max(minn, l - pos[i] + 1); printf("%d %d", minn, maxx); return 0; }

傳紙條 & 方格取數

多維dp的應用

code傳紙條

#include<iostream>
#include
<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> using namespace std; const int N = 60; int n, m, a[N][N], dp[N][N][N][N]; inline int myMax(int u, int v, int x, int y){ int ret = u; ret = max(ret, v); ret = max(ret, x); ret
= max(ret, y); return ret; } int main(){ scanf("%d%d", &m, &n); for(int i = 1; i <= m; i++) for(int j = 1; j <= n; j++) scanf("%d", &a[i][j]); dp[1][1][1][1] = a[1][1]; for(int i = 1; i <= m; i++) for(int j = 1; j <= n; j++) for(int k = 1; k <= m; k++) for(int l = 1; l <= n; l++){ if(i == 1 && j == 1) continue; dp[i][j][k][l] = myMax(dp[i - 1][j][k - 1][l], dp[i][j - 1][k - 1][l], dp[i - 1][j][k][l - 1], dp[i][j - 1][k][l - 1]) + a[i][j] + a[k][l]; if(i == k && j == l) dp[i][j][k][l] -= a[i][j]; } printf("%d", dp[m][n][m][n]); return 0; }

code方格取數

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

const int N = 15;
int n, a[N][N], dp[N][N][N][N];

inline int myMax(int u, int v, int x, int y){
    int ret = u;
    ret = max(ret, v);
    ret = max(ret, x);
    ret = max(ret, y);
    return ret;
}

int main(){
    scanf("%d", &n);
    int x, y, w;
    while(scanf("%d%d%d", &x, &y, &w), x + y + w)
        a[x][y] = w;
//    dp[1][1][1][1] = a[1][1];
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            for(int k = 1; k <= n; k++)
                for(int l = 1; l <= n; l++){
//                    if(i == k && j == l && i != n && j != n) continue;
                    dp[i][j][k][l] = myMax(dp[i - 1][j][k - 1][l], dp[i][j - 1][k - 1][l],
                                           dp[i - 1][j][k][l - 1], dp[i][j - 1][k][l - 1])
                                     + a[i][j] + a[k][l];
                    if(i == k && j == l )
                        dp[i][j][k][l] -= a[i][j];    
                }
    printf("%d", dp[n][n][n][n]);
    return 0;
}

矩陣取數遊戲

問題識破 + dp + 高精度

技術分享
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;

inline int read(){
    int i = 0, f = 1; char ch = getchar();
    for(; (ch < 0 || ch > 9) && ch != -; ch = getchar());
    if(ch == -) f = -1, ch = getchar();
    for(; ch >= 0 && ch <= 9; ch = getchar())
        i = (i << 3) + (i << 1) + (ch - 0);
    return i * f;
}

const int N = 100;
int n, m;

struct bign{
    int len, s[N];
    bign():len(1){memset(s, 0, sizeof s);}
    inline void clear(){
        while(len > 1 && s[len] == 0) len--;
    }
    inline bign operator * (const bign &u) const{
        bign ret;
        ret.len = len + u.len + 10;
        for(int i = 1; i <= len; i++)
            for(int j = 1; j <= u.len; j++)
                ret.s[i + j - 1] += s[i] * u.s[j];
        for(int i = 1; i <= ret.len; i++)
            if(ret.s[i] >= 10){
                ret.s[i + 1] += ret.s[i] / 10;
                ret.s[i] %= 10;
            }
        ret.clear();
        return ret;
    }
    inline void print(){
        clear();
        for(int i = len; i >= 1; i--)
            putchar(s[i] + 0);
    }
    inline bool operator > (const bign &u) const{ 
        if(len != u.len) return len > u.len;
        for(int i = len; i >= 1; i--)
            if(s[i] != u.s[i]) return s[i] > u.s[i];
        return false;
    }
    inline bign operator + (const bign &u) const{
        bign ret;
        ret.len = 0;
        int i, g;
        for(i = 1, g = 0; g || i <= max(len, u.len); i++){
            ret.s[++ret.len] = g;
            if(i <= len) ret.s[ret.len] += s[i];
            if(i <= u.len) ret.s[ret.len] += u.s[i];
            g = ret.s[ret.len] / 10;
            ret.s[ret.len] %= 10;
        }
        ret.clear();
        return ret;
    }
}pow2[N][N], f[N][N], big2, ans, ret, a[N], big0;

inline bign newBign(int x){
    bign ret;
    ret.len = 0;
    while(x){
        ret.s[++ret.len] = x % 10;
        x /= 10;
    }
    if(ret.len == 0) ret.len = 1;
    return ret;
}

inline void initPow(){
    for(int i = 1; i <= m; i++)
        for(int j = 1; j <= m; j++)
            pow2[i][j] = pow2[i][j - 1] + pow2[i][j - 1];
}

inline bign max(bign a, bign b){
    return a > b ? a : b;
}

int main(){
    n = read(), m = read();
    ans = big0 = newBign(0); big2 = newBign(2);
    for(int t = 1; t <= n; t++){
        ret = big0;
        for(int i = 1; i <= m; i++) pow2[i][0] = newBign(read());
        initPow();
        for(int i = 0; i <= m; i++)
            for(int j = 0; j <= m; j++)
                f[i][j] = big0;
        for(int i = 0; i <= m; i++)
            for(int j = 0; i + j <= m; j++){
                if(i > 0) f[i][j] = max(f[i - 1][j] + pow2[i][i + j], f[i][j]);
                if(j > 0) f[i][j] = max(f[i][j - 1] + pow2[m - j + 1][i + j], f[i][j]);
            }
        for(int i = 0; i <= m; i++)
            ret = max(ret, f[i][m - i]);
        ans = ans + ret;
    }
    ans.print();
    return 0;
}
View Code

鋪地毯

怎麽說呢

#include<iostream>
#include<cstdio>
using namespace std;

const int N = 1e4 + 5;
int n, x1[N], y1[N], l[N], w[N], x, y, ans = -1;

int main(){
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d%d%d%d", &x1[i], &y1[i], &l[i], &w[i]);
    scanf("%d%d", &x, &y);
    for(int i = n; i >= 1; i--){
        if(x1[i] <= x && x <= x1[i] + l[i] - 1 && y1[i] <= y && y <= y1[i] + w[i] - 1){
            ans = i;
            break;
        }
    }
    printf("%d", ans);
    return 0;
}

noip刷題記錄 20170823