zoukankan      html  css  js  c++  java
  • 2017 清北济南考前刷题Day 6 morning

     T1

     贪心

    10 元先找5元

    20元 先找10+5,再找3张5

    #include<cstdio>
    
    using namespace std;
    
    int m5,m10,m20;
    
    int main()
    {
        freopen("book.in","r",stdin);
        freopen("book.out","w",stdout);
        int n;
        scanf("%d",&n);
        int x;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            if(x==5) m5++;
            else if(x==10)
            {
                if(!m5) { puts("NO"); return 0; }
                m5--; m10++;
            }
            else
            {
                if(m10 && m5) m10--,m5--;
                else if(m5>=3) m5-=3;
                else { puts("NO"); return 0; }
            }
        }
        puts("YES"); return 0;
    }
    View Code

     T2

     

     小c记得的出口位置看做左括号

    从右往左扫描 信息

    左括号入栈

    否则判断当前栈顶 是否能匹配,

    匹配则为右括号,不匹配当左括号入栈

    栈空则有解,非空则无解

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    #define N 1000001
    
    using namespace std;
    
    int a[N];
    
    int st[N],top;
    
    bool zf[N];
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    int main()
    {
        freopen("program.in","r",stdin);
        freopen("program.out","w",stdout);
        int n,m;
        read(n);
        for(int i=1;i<=n;++i) read(a[i]);
        read(m);
        int x;
        for(int i=1;i<=m;++i)
        {
            read(x);
            if(a[x]>0) a[x]=-a[x];
        }
        for(int i=n;i;--i)
        {
            if(a[i]<0) st[++top]=a[i],zf[i]=true;
            else
            {
                if(st[top]==-a[i]) top--;
                else st[++top]=-a[i],zf[i]=true;
            }
        }
        if(top) { puts("NO"); return 0; }
        for(int i=1;i<=n;i++)
        {
            if(!zf[i]) printf("+%d ",abs(a[i]));
            else printf("-%d ",abs(a[i]));
        }
        fclose(stdin); fclose(stdout); 
        return 0;
    }
    View Code

    不会spj所以不知道对错的代码

    对于一个出口,判断前面是否有足够的入口

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define N 1000001
    
    int a[N],b[N];
    int tot[N],pre[N];
    
    int outtot[N];
    
    bool out[N],zf[N];
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    int main()
    {
        freopen("program.in","r",stdin);
        freopen("program.out","w",stdout);
        int n; read(n);
        int x;
        for(int i=1;i<=n;i++)
        {
            read(x); a[i]=x;
            pre[i]=++tot[x];
        }
        int m; read(m);
        for(int i=1;i<=m;++i) read(b[i]);
        sort(b+1,b+m+1);
        int t=unique(b+1,b+m+1)-b-1;
        for(int i=1;i<=t;i++) 
        {
            x=b[i];
            outtot[a[x]]++; out[x]=true;
            if(pre[x]<outtot[a[x]]*2) { puts("NO"); return 0; }
        }
        for(int i=1;i<=n;i++)
            if(tot[i]&1) { puts("NO"); return 0; }
        for(int i=1;i<=n;i++)
        {
            if(out[i]) printf("-%d ",a[i]);
            else if(outtot[a[i]]) printf("+%d ",a[i]),outtot[a[i]]--;
            else if(!zf[a[i]]) printf("+%d ",a[i]),zf[a[i]]^=1;
            else printf("-%d ",a[i]),zf[a[i]]^=1;
        }
    }
    View Code

    T3 

    把钥匙看做左括号,门看做右括号

    模拟括号匹配,任意两点间只有两种状态:匹配,缺右括号

    那么问题转化为 从a走到b 能否括号匹配

     

    宽搜+DP

    dp[i][j][k]表示 点i到点j 是否有状态k

    k=0 表示 i到j的路径上能够括号匹配

    k:1——10 表示 点i到j的路径上,栈顶为右括号k

    k:11——20 表示点i到j的路径上,栈顶为左括号k,即缺右括号k

     

    每次更新一个ijk,就相当于在ij之间连一条状态为k的边,扔进队列里

    从队列里取出 从u到v的状态为w的边

    如果w=0,那么 枚举状态k (0,11——20)

    if dp[i][u][k]=true  更新 dp[i][v][k]  

    if dp[v][i][k]=true  更新 dp[u][i][k]

    如果w!=0,那么 只能去找右括号

    即if dp[v][i][w-10] 更新 dp[u][i][0]

    为什么 w=0 是双向更新,w!=0是单项更新?

    因为只能是栈中有左括号的情况下,右括号才能入栈

    对于每一次询问,判断dp[u][v][0] 即可

    #include<cstdio>
    
    using namespace std;
    
    bool dp[101][101][21];
    
    int head,tail;
    
    int q[100001][3];
    
    int main()
    {
        freopen("maze.in","r",stdin);
        freopen("maze.out","w",stdout);
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i) dp[i][i][0]=true;
        int u,v,w;
        while(m--)
        {
            scanf("%d%d%d",&u,&v,&w);
            if(!w)
            {
                dp[u][v][w]=dp[v][u][w]=true;
                q[tail][0]=u; q[tail][1]=v; q[tail++][2]=w;
                q[tail][0]=v; q[tail][1]=u; q[tail++][2]=w;
            }
            else if(w<0)
            {
                w=-w;
                dp[u][v][w]=dp[v][u][w]=true;
            }
            else
            {
                w+=10;
                dp[u][v][w]=dp[v][u][w]=true;
                q[tail][0]=u; q[tail][1]=v; q[tail++][2]=w;
                q[tail][0]=v; q[tail][1]=u; q[tail++][2]=w;
            }
        }
        while(head<tail)
        {
            u=q[head][0]; v=q[head][1]; w=q[head++][2];
            if(!w)
            {
                for(int i=1;i<=n;++i)
                {
                    if(dp[i][u][0] && !dp[i][v][0])
                    {
                        dp[i][v][0]=true;
                        q[tail][0]=i; q[tail][1]=v; q[tail++][2]=0;
                    }
                    if(dp[v][i][0] && !dp[u][i][0])
                    {
                        dp[u][i][0]=true;
                        q[tail][0]=u; q[tail][1]=i; q[tail++][2]=0;
                    }
                    for(int j=11;j<=20;++j)
                    {
                        if(dp[i][u][j] && !dp[i][v][j])
                        {
                            dp[i][v][j]=true;
                            q[tail][0]=i; q[tail][1]=v; q[tail++][2]=j;
                        }
                    }
                }
            }
            else
            {
                for(int i=1;i<=n;++i)
                {
                    if(dp[v][i][w-10] && !dp[u][i][0])
                    {
                        dp[u][i][0]=true;
                        q[tail][0]=u; q[tail][1]=i; q[tail++][2]=0;
                    }
                }
            }
        }
        int q;
        scanf("%d",&q);
        while(q--)
        {
            scanf("%d%d",&u,&v);
            puts(dp[u][v][0] ? "YES" : "NO");
        }
    }
    View Code
  • 相关阅读:
    关于javascript app框架的几篇文章
    php 开发笔记
    php 图片处理扩展(windows平台)
    [javascript]最短 domready
    javascript小陷阱
    HTML DOM whiteSpace
    40岁后才明白的道理:人一生奋斗余地很有限转载
    [学习笔记]lca倍增
    Django model 字段类型及选项解析转载
    PythonPEP8 风格规范指南
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7772914.html
Copyright © 2011-2022 走看看