• 暑假第二十七测


    今天是我调代码最久的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
    ",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
    ",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
    ", min(dis[tx][ty][1], min(dis[tx][ty][0], dis[tx][ty][2])));
        
    }
    View Code

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

  • 相关阅读:
    随笔
    3.1作业
    关于JavaDate数据返回到前端变数字的问题(并引申到前后端时间的传输)
    utf-8转换为base64
    base64转换为utf-8
    Java Web基础——jsp调用动态界面
    Java Web基础——JSP指令标记
    2020软件工程最后一次作业
    软件工程第二次结对作业
    软件工程第三次作业
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9550707.html
Copyright © 2020-2023  润新知