• 平时一测


    第一题:SPFA,最难的还是读入,一般读入接上一行的 ;

    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<queue>
    using namespace std;
    
    
    const int M = 4005;
    int S, T, p, h[M], tot, dis[M];
    bool inq[M];
    struct edge{int v, nxt;}G[M];
    void add(int u, int v){
        G[++tot].v = v; G[tot].nxt = h[u]; h[u] = tot;
    }
    inline int rec(int z){
        int t = (z + 19) / 20 + z;
        while(t - (t + 19) / 20 < z)t++;
        return t;
    }
    void spfa(){
        queue <int> Q;
        memset(dis, 127, sizeof(dis));
        memset(inq, 0, sizeof(inq));
        Q.push(T);
        
        dis[T] = p;
        inq[T] = 1;
        
        while(!Q.empty()){
            int u = Q.front(); Q.pop(); inq[u] = 0;
            for(int i = h[u]; i; i = G[i].nxt){
                int v = G[i].v;
                int w = u >= 100 ? rec(dis[u]) : dis[u] + 1;
                if(w < dis[v]){
                    dis[v] = w;
                    if(!inq[v])Q.push(v), inq[v] = 0;
                }
            }
        }
    }
    
    
    inline void get(char a, char b){
        int u, v;
        if(a <='Z' && a >='A')
            u = a-'A' + 100;
        else u = a-'a';
        
        if(b <='Z' && b >='A')
            v = b-'A' + 100;
        else v = b-'a';
        add(v, u); add(u, v);
    }
    void init(char a, char b){
        int u, v;
        if(a <='Z' && a >='A')
            u = a-'A' + 100;
        else u = a-'a';
        
        if(b <='Z' && b >='A')
            v = b-'A' + 100;
        else v = b-'a';
        S = u, T = v;
    }
    
    void cls(){
        memset(h, 0, sizeof(h));
        tot = 0;
    }
    int main(){
        freopen("toll.in","r",stdin);
        freopen("toll.out","w",stdout);
        int n, idc = 0;
        while(scanf("%d", &n) == 1 && n != -1){
            idc++;
            cls();
            char a, b, s, t;
            for(int i = 1; i <= n; i++){
                scanf("
    %c %c", &a, &b);
            //    printf("%c %c
    ", a, b);
                get(a, b);
            }
            scanf("%d %c %c", &p, &s, &t);
            //printf("start %c %c
    ",s, t);
            init(s, t);
            spfa();
            printf("Case %d: %d
    ", idc,dis[S]);
        }    
    }

    第二题:LIS即为答案,一个逆序对一条边,只有LIS里面没有边,应该多想一下,这道题很简单,但我方向完全偏了;

    第三题:搜索+剪枝,所有数据都很小,所以可以实际跑的很快,本来想状压没搞出来;

    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<queue>
    using namespace std;
    #define For(a, b, c) for(int a = b; a <= c; a++)
    const int M = (1 << 14) + 1;
    int visr[M], visg[M], visw[M], ans, n;
    struct POINT{int sr,sg,kr,kg,kw;}d[15];
    inline bool better(int s, int rr, int gg, int ww){
        int nw = visw[s], tt = visr[s] - rr;
        if(tt > 0) ww -= tt;
        else nw += tt;
        if(ww + gg < visg[s] + nw || ( rr == visr[s] && gg == visg[s] && ww == visw[s]) )return 0; 
        visr[s] = max(visr[s], rr); 
        visw[s] = max(visw[s], ww); 
        visg[s] = max(visg[s], gg); 
        return 1;
    } 
    
    
    void dfs(int dep, int sta, int rr, int gg, int ww){
        //printf("%d %d %d %d
    ",sta, rr,gg,ww);
        ans = max(ans, rr + gg + ww);
        if(dep == n + 1)return ;
        if(!better(sta, rr, gg, ww))return;
        for(int i = 1; i <= n; i++)
            if(!(sta & (1 << (i - 1)))){
                if(d[i].sr <= rr + ww){        
                    int nr = rr >= d[i].sr ? rr - d[i].sr : 0;
                    int nw = rr >= d[i].sr ? ww : ww - (d[i].sr - rr);    
                    int ng = gg >= d[i].sg ? gg - d[i].sg : 0;
                    nw = gg >= d[i].sg ? nw : nw - (d[i].sg - gg);
                    if(nw < 0)continue;
                    dfs(dep + 1, sta | (1 << (i - 1)), nr + d[i].kr, ng + d[i].kg, 
                    nw + d[i].kw);
                }
            }
                
    }
    
    int main(){
        //freopen("room.in","r",stdin);
        //freopen("room.out","w",stdout);
        int k0, k1, k2;
        scanf("%d", &n);
        memset(visg, -1, sizeof(visg));
        memset(visr, -1, sizeof(visr));
        memset(visw, -1, sizeof(visw));
        For(i, 1, n) scanf("%d", &d[i].sr);
        For(i, 1, n) scanf("%d", &d[i].sg);
        For(i, 1, n) scanf("%d", &d[i].kr);
        For(i, 1, n) scanf("%d", &d[i].kg);
        For(i, 1, n) scanf("%d", &d[i].kw);
    /*    For(i, 1, n)
            d[i].tot = d[i].kr + d[i].kg + d[i].kw;
    */    scanf("%d%d%d", &k0, &k1, &k2); //0 red 1 green 2 white
    
        ans = k0 + k1 + k2;
        dfs(1, 0, k0, k1, k2);
        printf("%d
    ",ans);
    }
    View Code

    今天题应该是很水的,然而考的不好,思维僵硬了;

  • 相关阅读:
    BZOJ2457 双端队列 题解
    POJ1723,1050,HDU4864题解(贪心)
    Splay与FHQ-Treap
    POJ3179 Corral the Cows题解
    使用easypoi根据表头信息动态导出excel
    Spring @Configuration注解
    vue脚手架vue-cli的搭建
    使用poi导出excel
    mybatis中的一对多和多对一
    angularjs模态框的使用
  • 原文地址:https://www.cnblogs.com/EdSheeran/p/9606457.html
Copyright © 2020-2023  润新知