暑假第二十七测

时间:2022-12-13 20:06:14

今天是我调代码最久的y一天

暑假第二十七测

暑假第二十七测

暑假第二十七测

暑假第二十七测

暑假第二十七测

暑假第二十七测

暑假第二十七测

暑假第二十七测

题解:

第一题:

暑假第二十七测

check的时候记录c字符从左区间向右第一次出现cmin, 和最后一次出现cmax;

如果这个区间合法,就有cmax(c -1) < cmin(c);

这道题的细节很多,比如其中一个字符没有出现怎么办(数据中每组都有这种情况,还有边界的取舍);

我调了一下午,最后又是请zjj同学帮我看的, 结果多组数据初值没有搞好

暑假第二十七测暑假第二十七测
#include<bits/stdc++.h>
using namespace std;
const int M = 100005;
int T, C, cmin[5], cmax[5], L;
int m, a[5], t[5], p[M][5][2], pos[M];



void check(int len){
    for(int c = 0; c < C; c++)cmax[c] = 0, cmin[c] = len;
    for(int lf = 1; lf <= L; ){
        int rg = min(lf + len - 1, L);
        for(int c = 0; c < C; c++){
            if(p[rg][c][0] >= lf)cmax[c] = max(cmax[c], p[rg][c][0] - lf + 1);
            if(p[lf][c][1] <= rg)cmin[c] = min(cmin[c], p[lf][c][1] - lf );
        }    
        lf += len;
    }

    
    for(int c = 0; c < C; c++){
        if(cmax[c] == 0)
            cmin[c] = c ? cmax[c - 1] : 0, cmax[c] = cmin[c] + 1;
        else if(cmin[c] > (c ? cmax[c - 1] : 0))
            cmin[c] = c ? cmax[c - 1] : 0;
        else if(c && cmin[c] < cmax[c - 1])return ;
    }
    
    if(cmax[C - 1] > len)return;
    cmax[C - 1] = len;
    for(int c = 0; c < C; c++){
        t[c] = cmax[c] - cmin[c];
        if(t[c] > a[c])return;
    }
    for(int c = 0; c < C; c++)a[c] = t[c];
}

int fg = 0;
int main(){
    freopen("char.in","r",stdin);
    freopen("char.out","w",stdout);
    scanf("%d%d", &T, &C);
    while(T--){
        scanf("%d", &m);
        L = 0;
        fg++;
        memset(pos, 0, sizeof(pos));
        for(int i = 1; i <= m; i++){
            int t, z;
            scanf("%d%d", &t, &z);
            L = max(L, t); pos[t] = z + 1;
        }
        for(int c = 0; c < C; c++)a[c] = L + C + 1;
        for(int i = 1; i <= L; i++){
            for(int c = 0; c < C; c++)
                p[i][c][0] = p[i - 1][c][0];
            if(pos[i]) p[i][pos[i] - 1][0] = i;    
        }
        for(int c = 0; c < C; c++)p[L + 1][c][1] = L + 1;
        for(int i = L; i; i--){
            for(int c = 0; c < C; c++)
                p[i][c][1] = p[i + 1][c][1];
            if(pos[i]) p[i][pos[i] - 1][1] = i;
        }
        for(int len = C; len < C + L; len++)
            check(len);
        if(a[0] == L + C + 1)puts("NO");
        else {
            for(int c = 0; c < C; c++)printf("%d ", a[c]);
            puts("");
        }
    }
}
View Code

 

第二题:

暑假第二十七测

老师说这道题没做出来,根基不牢,我就只能呵呵了

暑假第二十七测暑假第二十七测
#include<bits/stdc++.h>
using namespace std;
const int M = 2005;
#define ll long long
ll dp[2][M], a[M << 1];
int n;
const ll inf = 1e15;
inline int moc(int i){return i ? i : n;}
int main(){
    freopen("cake.in","r",stdin);
    freopen("cake.out","w",stdout);
    
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)scanf("%I64d", a + i), a[n + i] = a[i], dp[0][i] = a[i];
    ll ans = 0;
    
    a[0] = a[n];
    int l, o;
    for( l = 1, o = 0; l < n; l++, o ^= 1){
        for(int i = 1; i <= n; i++)dp[o ^ 1][i] = -inf;
        
        if(o)
            for(int i = 1; i <= n; i++){
                dp[0][moc(i - 1)] = max(dp[0][moc(i - 1)], dp[1][i] + a[i - 1]);
                dp[0][i] = max(dp[0][i], dp[1][i] + a[i + l]);
            }
        else for(int i = 1; i <= n; i++){
                if(a[i - 1] >= a[i + l])dp[1][moc(i - 1)] = max(dp[1][moc(i - 1)], dp[0][i]);
                if(a[i - 1] <= a[i + l])dp[1][i] = max(dp[1][i], dp[0][i]);
        }
        //for(int i = 1; i <= n; i++)printf("%I64d ", dp[o ^ 1][i]);puts("");
    }
    for(int i = 1; i <= n; i++)
        ans = max(ans, dp[o][i]);
    
    printf("%I64d\n",ans);
    
}
View Code

 

第三题:

暑假第二十七测

多个方向移动,拆点多状态的思想;但是建边复杂度很高,只能边跑边建边,用dijistra第一次跑到最优,就可以少建边了

暑假第二十七测暑假第二十七测
#include<bits/stdc++.h>
using namespace std;
#define For(a, b, c) for(int a = b; a <= c; a++)
const int M = 2 * 1e6;
#define ll long long
const ll inf = 1e18;
ll dis[505][505][3], dir[505][505];
int q[M >> 1];
int zl[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
struct sta{
    int k, x, y; ll dis;
    bool operator < (const sta & rhs) const{
        return dis > rhs.dis;
    }
};
priority_queue <sta> Q;


int main(){
    freopen("game.in","r",stdin);
    freopen("game.out","w",stdout);
    int X, Y, N, sx, sy, tx, ty;
    ll A, B, C;
    scanf("%d%d%I64d%I64d%I64d%d", &X, &Y, &A, &B, &C, &N);
    memset(dir, -1, sizeof(dir));
    For(i, 1, N){
        int x, y;
        scanf("%d%d", &x, &y);
        dir[x][y] = 0;
        if(i == 1)sx = x, sy = y;
        if(i == N)tx = x, ty = y;
    }
    int lf = 0, rg = 0;
    For(x, 0, X)
        For(y, 0, Y)
            if(!dir[x][y]) q[++rg] = x, q[++rg] = y;
    while(lf != rg){
        int x = q[++lf], y = q[++lf];
        for(int k = 0; k < 4; k++){
            int u = x + zl[k][0], v = y + zl[k][1];
            if((u >= 0 && u <= X && v <= Y && v >= 0) && dir[u][v] == -1){
                dir[u][v] = dir[x][y] + C;
                q[++rg] = u, q[++rg] = v;
            }
        }
    }
    
    For(x, 0, X)
        For(y, 0, Y)
            For(k, 0, 3)dis[x][y][k] = inf + 1;
    
    Q.push((sta) { 2, sx, sy, 0 });
    while(!Q.empty()){
        sta u = Q.top(); Q.pop();
        if(dis[u.x][u.y][u.k] < inf)continue;
        dis[u.x][u.y][u.k] = u.dis;
        //printf("%d %d %d %I64d\n",u.x,u.y,u.k,u.dis);
        if(u.x == tx && u.y == ty)break;
        switch(u.k){
            case 2:{
                if(dis[u.x][u.y][0] > inf)Q.push((sta){0, u.x, u.y, u.dis + B});
                if(dis[u.x][u.y][1] > inf)Q.push((sta){1, u.x, u.y, u.dis + B});
                for(int k = 0; k < 4; k++){
                    int vx = u.x + zl[k][0], vy = u.y + zl[k][1];
                    if(vx >= 0 && vx <= X && vy >= 0 && vy <= Y && dis[vx][vy][2] > inf) Q.push((sta){2, vx, vy, u.dis + C});
                }
                break;
            }
            default:{
                if(dis[u.x][u.y][2] > inf) Q.push((sta){2, u.x, u.y, u.dis + dir[u.x][u.y]});
                for(int k = u.k; k < 4; k += 2){
                    int vx = u.x + zl[k][0], vy = u.y + zl[k][1];
                    if(vx >= 0 && vx <= X && vy >= 0 && vy <= Y && dis[vx][vy][u.k] > inf) Q.push((sta){u.k, vx, vy, u.dis + A});
                }
            }
        }
    }
    
    printf("%I64d\n", min(dis[tx][ty][1], min(dis[tx][ty][0], dis[tx][ty][2])));
    
}
View Code

 

最后在说一句,林荫的大佬太强啦,完全吊打我们这边的