zoukankan      html  css  js  c++  java
  • NOIP2014 提高组合集

    NOIP 2014 提高组 合集

    D1 T1 生活大爆炸版石头剪刀布

    首先,先将两个人的猜拳序列都变得不小于n。然后逐个模拟。胜败什么的看表就行了。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int ans1=0,ans2=0;
    int a1[210],a2[210],s1[210],s2[210],k1,k2;
    void calc(int x,int y)
    {
        if(x==0)
        {
            if(y==0) return;
            else if(y==1) ans2++;
            else if(y==2) ans1++;
            else if(y==3) ans1++;
            else ans2++;
        }
        else if(x==1)
        {
            if(y==0) ans1++;
            else if(y==1) return;
            else if(y==2) ans2++;
            else if(y==3) ans1++;
            else ans2++;
        }
        else if(x==2)
        {
            if(y==0) ans2++;
            else if(y==1) ans1++;
            else if(y==2) return;
            else if(y==3) ans2++;
            else ans1++;
        }
        else if(x==3)
        {
            if(y==0) ans2++;
            else if(y==1) ans2++;
            else if(y==2) ans1++;
            else if(y==3) return;
            else ans1++;
        }
        else
        {
            if(y==0) ans1++;
            else if(y==1) ans1++;
            else if(y==2) ans2++;
            else if(y==3) ans2++;
            else return;
        }
    }
    int main()
    {
        int n,n1,n2; cin >> n >> n1 >> n2 ;
        for(int i=1;i<=n1;i++) scanf("%d",&a1[i]);
        for(int i=1;i<=n2;i++) scanf("%d",&a2[i]);
        int cnt1=n/n1+(n%n1==0?0:1),cnt2=n/n2+(n%n2==0?0:1);
        for(int i=1;i<=cnt1;i++) for(int j=1;j<=n1;j++) s1[++k1]=a1[j];
        for(int i=1;i<=cnt2;i++) for(int j=1;j<=n2;j++) s2[++k2]=a2[j];
        for(int i=1;i<=n;i++) calc(s1[i],s2[i]);
        printf("%d %d
    ",ans1,ans2);
        return 0;
    }
    

    D1 T2 联合权值

    巨裸的树形dp,跟模拟没啥区别了。我开始看成了边不给定,然后管教练要prufer的ppt... ...

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 200010 
    #define mod 10007 
    using namespace std; typedef long long ll; ll maxn=0,ans=0;
    ll w[N]; int to[N<<1],head[N],nxt[N<<1],tot;
    inline char nc() {static char *p1,*p2,buf[100000]; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;} 
    ll rd() {ll x=0; char c=nc(); while(!isdigit(c)) c=nc(); while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=nc(); return x;}
    inline void add(int x,int y) {to[++tot]=y; nxt[tot]=head[x]; head[x]=tot;}
    void dfs(int pos,int fa)
    {
        ll now1=w[fa],now2=0; ll sum=w[fa]%mod;
        for(int i=head[pos];i;i=nxt[i]) if(to[i]!=fa)
        {
            // printf("%d")
            if(w[to[i]]>=now1) now2=now1,now1=w[to[i]];
            else if(w[to[i]]>=now2) now2=w[to[i]];
            (ans+=sum%mod*w[to[i]]%mod)%=mod; (sum+=w[to[i]])%=mod;
            dfs(to[i],pos);
        }
        maxn=max(maxn,now1*now2);
    }
    // void test()
    // {
    // 	puts("Fuck"); for(int i=1;i<=n;i++) 
    // }
    int main()
    {
        int n=rd(); int x,y; for(int i=1;i<n;i++) x=rd(),y=rd(),add(x,y),add(y,x);
        for(int i=1;i<=n;i++) w[i]=rd();
        dfs(1,0); printf("%lld %lld
    ",maxn,ans*2%mod);
    }
    

    D1 T3 飞扬的小鸟
    dp题。f[i][j]表示横坐标到i,高度到j的最少点击次数。

    转移的话,上升我们考虑完全背包,下降用01背包即可。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=10000+10;
    const int M=2000+10;
    int n,m,p;
    int x[N],y[N];
    int low[N],high[N];
    int f[N][M];
    bool e[N]; 
    int main()
    {
        scanf("%d%d%d",&n,&m,&p);
        for(int i=1;i<=n;++i) scanf("%d%d",&x[i],&y[i]);
        for(int i=1;i<=n;++i)
        {
            low[i]=1;
            high[i]=m;
        }
        int a,b,c;
        for(int i=1;i<=p;++i)
        {
            scanf("%d%d%d",&a,&b,&c);
            e[a]=1;
            low[a]=b+1;
            high[a]=c-1;
        }
        memset(f,0x3f,sizeof(f));
        for(int i=1;i<=m;++i) f[0][i]=0;
        for(int i=1;i<=n;++i)
        {
            for(int j=x[i]+1;j<=m+x[i];++j)
                f[i][j]=min(f[i-1][j-x[i]]+1,f[i][j-x[i]]+1);
            for(int j=m+1;j<=m+x[i];++j)
                f[i][m]=min(f[i][m],f[i][j]);
            for(int j=1;j<=m-y[i];++j)
                f[i][j]=min(f[i][j],f[i-1][j+y[i]]);
            for(int j=1;j<low[i];++j)
                f[i][j]=f[0][0];
            for(int j=high[i]+1;j<=m;++j)
                f[i][j]=f[0][0];
        }
        int ans=f[0][0];
        for(int j=1;j<=m;++j)
        {
            ans=min(ans,f[n][j]);
        }
        if(ans<f[0][0]) printf("1
    %d
    ",ans);
        else
        {
            int i,j;
            for(i=n;i>=1;i--)
            {
                for(j=1;j<=m;++j)
                {
                    if(f[i][j]<f[0][0]) break;
                }
                if(j<=m) break;
            }
            ans=0;
            for(int j=1;j<=i;++j) if(e[j]) ans++;
            printf("0
    %d
    ",ans);
        }
        return 0;
    }
    

    D2 T1 无线网络发射器选址

     挨着枚举一遍就行...

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define N 150 
    using namespace std;
    int val[N][N]; int ans,tmp;
    int main()
    {
        int d,n; cin >> d >> n ; int x,y,a;
        for(int i=1;i<=n;i++) scanf("%d%d%d",&x,&y,&a),val[x][y]+=a;
        for(int i=0;i<=128;i++) for(int j=0;j<=128;j++)
        {
            int x1,y1,x2,y2;
            x1=max(0,i-d); x2=min(i+d,128);
            y1=max(0,j-d); y2=min(j+d,128);
            int now=0; for(int k=x1;k<=x2;k++) for(int l=y1;l<=y2;l++) now+=val[k][l];
            if(ans<now) ans=now,tmp=1;
            else if(ans==now) tmp++;
        }
        printf("%d %d
    ",tmp,ans);
    }
    

    D2 T2 寻找道路

    先连反向边,从终点先dfs一遍,把所有能到终点的点打上标记。然后对于所有到不了终点的点,枚举所有出边,枚举到的都是不能在路径上出现的点,紧接着连正向边,从原点跑dij即可。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #define N 10010 
    #define M 200010 
    #define mp make_pair
    using namespace std; queue<int>q; priority_queue<pair<int,int> >que;
    struct Node{int x,y;}a[M]; int head[N],nxt[M<<1],to[M<<1],tot;
    int f[N]; bool vis[N],in[N]; int n,m,s,t;
    inline char nc() {static char *p1,*p2,buf[100000]; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}
    int rd() {int x=0; char c=nc(); while(!isdigit(c)) c=nc(); while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=nc(); return x;}
    inline void add(int x,int y) {to[++tot]=y; nxt[tot]=head[x]; head[x]=tot;}
    void dfs(int pos,int fa)
    {
        if(vis[pos]) return;
        vis[pos]=true; for(int i=head[pos];i;i=nxt[i]) if(to[i]!=fa) dfs(to[i],pos);
    }
    void bfs()
    {
        for(int i=1;i<=n;i++) if(!vis[i]) in[i]=true;
        while(!q.empty())
        {
            puts("Fuck");
            int x=q.front(); q.pop();
            for(int i=head[x];i;i=nxt[i])
            {
                if(in[to[i]]) continue;
                in[to[i]]=true;
                q.push(to[i]);
            }
        }
    }
    void dij(int s)
    {
        memset(f,0x3f,sizeof f); memset(vis,false,sizeof vis);
        f[s]=0; que.push(mp(0,s)); vis[s]=1;
        while(!que.empty())
        {
            while(-que.top().first>f[que.top().second]&&!que.empty()) que.pop();
            if(que.empty()) return;
            int x=que.top().second; 
            que.pop(); for(int i=head[x];i;i=nxt[i])
            {
                // printf("%d %d
    ",que.top().first,que.top().second);
                if(f[to[i]]>f[x]+1&&!vis[to[i]])
                {
                    vis[to[i]]=true;
                    f[to[i]]=f[x]+1,que.push(mp(-f[to[i]],to[i]));
                }
            }
        }
    }
    void test()
    {
        for(int i=1;i<=n;i++) printf("%d ",in[i]?1:0); puts("");
    }
    int main()
    {
        n=rd(),m=rd();
        for(int i=1;i<=m;i++) a[i].x=rd(),a[i].y=rd(),add(a[i].y,a[i].x);
        s=rd(),t=rd(); dfs(t,t);
        for(int i=1;i<=n;i++) if(!vis[i])
        {
            in[i]=true;
            for(int j=head[i];j;j=nxt[j])
            {
                in[to[j]]=true;
            }
        }
        // test();
        memset(head,0,sizeof head); tot=0;
        for(int i=1;i<=m;i++)
        {
            if(in[a[i].x]||in[a[i].y]) continue;
            add(a[i].x,a[i].y);
            // printf("%d %d
    ",a[i].x,a[i].y);
        }
        dij(s); 
        if(f[t]==0x3f3f3f3f) puts("-1");
        else printf("%d
    ",f[t]);
        return 0;
    }
    

    D2 T3 解方程

    我去...这题,看了题解才明白出题人的意图... ...

    我做题的时候还在那里骂:卧槽,傻逼出题人又tm出高精度

    然后是个rp题...

    998244353可过。

    但是为了尊敬长者,我们用19260817

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #define mod 19260817
    using namespace std;
    typedef long long ll;
    bool t=true;
    int n,m,ans,cnt,sum=0;
    int A[103],key[1000003];
    inline char nc() {static char *p1,*p2,buf[100000]; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}
    ll rd()
    {
        ll x=0; char c=nc(); int f=1; if(c=='-') f=-1;
        while(!isdigit(c))
        {
            c=nc();
            if(c=='-') f=-1;
        }
        while(isdigit(c)) (x=(x<<3)%mod+(x<<1)%mod+(c^48)%mod)%=mod,c=nc();
        return x*f;
    }
    bool calc(ll x)
    {
        sum=0;
        for(ll i=n;i>=1;i--)
        {
            sum=((A[i]+sum)*x)%mod;
        }
        sum=(sum+A[0])%mod;
        return !sum;
    }
    int main()
    {
        n=rd();
        m=rd();
        for(ll i=0;i<=n;i++) A[i]=rd();
        for(ll i=1;i<=m;i++)
        {
            if(calc(i))
            { 
                t=false; 
                ans++;
                key[++cnt]=i;
            }
        }
        printf("%d
    ",ans);
        for(ll i=1;i<=cnt;i++) printf("%d
    ",key[i]);
        return 0;
    }
    
  • 相关阅读:
    《Linux内核分析》读书笔记(四章)
    LINUX内核分析第七周学习总结
    linux内核分析第六周学习笔记
    《Linux内核分析》第13章
    《Linux内核分析》实践4
    《Linux内核分析》实践3
    《Linux内核分析》实践2
    《Linux内核设计》第17章学习笔记
    实践指导1
    《Linux内核分析》期终总结&《Linux及安全》期中总结
  • 原文地址:https://www.cnblogs.com/ShuraK/p/9601596.html
Copyright © 2011-2022 走看看