zoukankan      html  css  js  c++  java
  • noip 2015 提高组

    T1 神奇的幻方 题目传送门 就只是一道模拟题 水水水

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int map[55][55],x[2507],y[2507],n;
    int main()
    {
        n=read();
        map[1][(n+1)/2]=1;
        x[1]=1; y[1]=(n+1)/2;
        for(int i=2;i<=n*n;i++){
            int nx=x[i-1],ny=y[i-1];
            if(nx==1&&ny<n) map[n][ny+1]=i,x[i]=n,y[i]=ny+1;
            else if(nx!=1&&ny==n) map[nx-1][1]=i,x[i]=nx-1,y[i]=1;
            else if(nx==1&&ny==n) map[nx+1][ny]=i,x[i]=nx+1,y[i]=ny;
            else if(nx!=1&&ny!=n){
                if(!map[nx-1][ny+1]) map[nx-1][ny+1]=i,x[i]=nx-1,y[i]=ny+1;
                else map[nx+1][ny]=i,x[i]=nx+1,y[i]=ny;
            }
        }
        for(int i=1;i<=n;i++,printf("
    "))
            for(int j=1;j<=n;j++)
                printf("%d ",map[i][j]);
        return 0;
    }
    View Code

    T2 信息传递 题目传送门

    这道题呢 搞一波tarjan缩点 最小的环就是答案了哇 不过一个点自成一环的不能算

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int M=250007;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int n,ans=M;
    int top,st[M],book[M];
    int low[M],dfn[M],sum;
    int first[M],cnt;
    struct node{int to,next;}e[2*M];
    void ins(int a,int b){sum++; e[sum].to=b; e[sum].next=first[a]; first[a]=sum;}
    void dfs(int x){
        dfn[x]=low[x]=++sum;
        st[++top]=x; 
        book[x]=1;
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(!dfn[now]){
                dfs(now);
                low[x]=min(low[x],low[now]);
            }
            if(book[now]) low[x]=min(low[x],dfn[now]);
        }
        if(low[x]==dfn[x]){
            int sum=1;
            book[x]=0;
            while(st[top]!=x){
                int now=st[top--];
                book[now]=0;
                sum++;
            }
            top--;
            if(sum>1) ans=min(ans,sum);
        }
    }
    int main()
    {
        int x;
        n=read();
        for(int i=1;i<=n;i++) x=read(),ins(i,x);
        for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i);
        printf("%d
    ",ans);
        return 0;
    }
    View Code

    T3 斗地主 题目传送门

    很佩服写这道题的人 我比较懒所以就跳了...23333

     好的跑回来补题了 其实这道题没有想象中那么恶心

    考虑到如果没有顺子出牌次数应该是一定的

    所以dfs枚举顺子的怎么打 然后就算一波答案就好啦 

    orz vijos的一百个测试数据

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define LL long long
    using namespace std;
    const int inf=0x3f3f3f3f;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int T,n,x,ans;
    int num[15],sum[15];
    int calc(){
        int cnt=0,f=0; memset(sum,0,sizeof(sum));
        for(int i=0;i<=13;i++) sum[num[i]]++;
        if(num[0]==2) f=1;
        while(sum[4]&&sum[2]>=2) cnt++,f=0,sum[4]--,sum[2]-=2;
        while(sum[4]&&sum[1]>=2) cnt++,sum[4]--,sum[1]-=2;
        while(sum[4]&&sum[2]) cnt++,f=0,sum[4]--,sum[2]--;
        if(f) cnt++,sum[2]--;
        while(sum[3]&&sum[2]) cnt++,sum[3]--,sum[2]--;
        while(sum[3]&&sum[1]) cnt++,sum[3]--,sum[1]--;
        return cnt+sum[1]+sum[2]+sum[3]+sum[4];
    }
    void dfs(int step){
        if(step>=ans) return ;
        ans=min(ans,step+calc());
        for(int i=2;i<=13;i++){
            int now=i;
            while(num[now]>=3) now++;
            if(now-i>=2){
                for(int j=i+1;j<now;j++){
                    for(int k=i;k<=j;k++) num[k]-=3;
                    dfs(step+1);
                    for(int k=i;k<=j;k++) num[k]+=3;
                }
            }
        }
        for(int i=2;i<=13;i++){
            int now=i;
            while(num[now]>=2) now++;
            if(now-i>=3){
                for(int j=i+2;j<now;j++){
                    for(int k=i;k<=j;k++) num[k]-=2;
                    dfs(step+1);
                    for(int k=i;k<=j;k++) num[k]+=2;
                }
            }
        }
        for(int i=2;i<=13;i++){
            int now=i;
            while(num[now]) now++;
            if(now-i>=5){
                for(int j=i+4;j<now;j++){
                    for(int k=i;k<=j;k++) num[k]--;
                    dfs(step+1);
                    for(int k=i;k<=j;k++) num[k]++;
                }
            }
        }
    }
    int pd(int x){
        if(!x) return x;
        return x==1?13:x-1; 
    }
    int main()
    {
        T=read(); n=read();
        while(T--){
            memset(num,0,sizeof(num));
            for(int i=1;i<=n;i++) x=pd(read()),read(),num[x]++;
            ans=inf; dfs(0);
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

    T4 跳石头 题目传送门  这就是道简单的二分

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int s[50007],n,m,v;
    int l,r,k,old;
    int pd(int w){
        int ans=0,sum=0;
        for(int i=1;i<=n;i++)
        {
            if(s[i]-sum<=w) ans++;
            else    sum=s[i];
        }
        return ans<=m;
    }
    int main()
    {
        v=read(); n=read(); m=read();
        l=0; r=v+1;
        for(int i=1;i<=n;i++) s[i]=read();
        n++; s[n]=v;
        while(l<=r){
            int mid=(l+r)>>1;
            if(pd(mid)) l=mid+1;
            else r=mid-1;
        }
        printf("%d
    ",l);
        return 0;
    }
    View Code

    T5 子串 题目传送门 这道题就是个DP 自己讲得不好 推荐个博客吧 orz

    #include<cstdio>
    #include<cstring> 
    #include<algorithm>
    using namespace std;
    const int M=1507,mod=1000000007;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int n,m,cnt,now,last=1;
    char a[M],b[M];
    int f[2][M][M],s[2][M][M];
    int main()
    {
        n=read(); m=read(); cnt=read(); //printf("[%d %d %d]
    ",n,m,cnt);
        scanf("%s %s",a+1,b+1); //printf("%s %s",a+1,b+1);
        s[0][0][0]=s[1][0][0]=1;
        for(int i=1;i<=n;i++){
            now^=1; last^=1;
            for(int j=1;j<=m;j++){
                if(a[i]==b[j]) for(int k=1;k<=cnt;k++) 
                f[now][j][k]=(f[last][j-1][k]+s[last][j-1][k-1])%mod,s[now][j][k]=(s[last][j][k]+f[now][j][k])%mod;
                else for(int k=1;k<=cnt;k++) 
                f[now][j][k]=0,s[now][j][k]=s[last][j][k];
            }
        }
        printf("%d
    ",s[n%2][m][cnt]);
        return 0;
    }
    View Code

    T6 运输计划 题目传送门 

     这是道lca加二分 果然自己还是太弱了没写出来 看了波题解才懂的 orzzsn 推荐个博客吧

    我感觉吧 sum处理的时候就像是打标记一样所以sum【l【i】】++,sum【r【i】】++,sum【lca【i】-=2; 就是把l【i】到r【i】的路径打一波标记好处理 2333

    具体看思诺大爷的题解吧 orz

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int M=350007;
    int read(){
        int ans=0,f=1,c=getchar();
        while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
        return ans*f;
    }
    int l[M],r[M],lca[M],dis[M],deep[M],f[M][25],sum[M],v[M],T[M],vis[M];
    int n,m,x,y,w;
    int cnt,first[M];
    struct node{int to,next,w;}e[2*M];
    void ins(int a,int b,int w){cnt++; e[cnt].to=b; e[cnt].w=w; e[cnt].next=first[a]; first[a]=cnt;}
    void insert(int a,int b,int w){ins(a,b,w); ins(b,a,w);}
    void dfs(int x){
        vis[x]=1;
        for(int i=1;(1<<i)<=deep[x];i++) f[x][i]=f[f[x][i-1]][i-1];
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(!vis[now]){
                deep[now]=deep[x]+1;
                v[now]=e[i].w;
                dis[now]=dis[x]+v[now];
                f[now][0]=x;
                dfs(now);
            }
        }
    }
    int find(int x,int y){
        if(deep[x]<deep[y]) swap(x,y);
        int d=deep[x]-deep[y];
        for(int i=0;(1<<i)<=d;i++) if((1<<i)&d) x=f[x][i];
        if(x==y) return x;
        for(int i=25;i>=0;i--)
         if((1<<i)<=deep[x]&&f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
        return f[x][0];
    }
    void push_sum(int x){
        for(int i=first[x];i;i=e[i].next){
            int now=e[i].to;
            if(now!=f[x][0]) push_sum(now),sum[x]+=sum[now];
        }
    }
    int check(int mid){
        int cnt=0,cmax=0;
        for(int i=1;i<=n;i++) sum[i]=0;
        for(int i=1;i<=m;i++) if(T[i]>mid){
            cnt++; cmax=max(cmax,T[i]-mid); 
            sum[l[i]]++; sum[r[i]]++; sum[lca[i]]-=2;
        }
        push_sum(1);
        for(int i=1;i<=n;i++) 
         if(sum[i]==cnt&&v[i]>=cmax) return 1;
        return 0;
    }
    int main()
    {
        n=read(); m=read();
        for(int i=1;i<n;i++) x=read(),y=read(),w=read(),insert(x,y,w);
        dfs(1);
        for(int i=1;i<=m;i++){
            l[i]=read(); r[i]=read(); 
            lca[i]=find(l[i],r[i]);
            T[i]=dis[l[i]]+dis[r[i]]-2*dis[lca[i]];
        }
        //for(int i=1;i<=m;i++) printf("[%d %d %d %d]
    ",l[i],r[i],lca[i],T[i]);
        int L=0,R=0;
        for(int i=1;i<=m;i++) R=max(R,T[i]);
        while(L<=R){
            int mid=(L+R)>>1;
            if(check(mid)) R=mid-1;
            else L=mid+1;
        }
        printf("%d
    ",L);
        return 0;
    }
    View Code
  • 相关阅读:
    heat模板
    Leetcode812.Largest Triangle Area最大三角形面积
    Leetcode812.Largest Triangle Area最大三角形面积
    Leetcode811.Subdomain Visit Count子域名访问计数
    Leetcode811.Subdomain Visit Count子域名访问计数
    Leetcode806.Number of Lines To Write String写字符串需要的行数
    Leetcode806.Number of Lines To Write String写字符串需要的行数
    Leetcode819.Most Common Word最常见的单词
    Leetcode819.Most Common Word最常见的单词
    Leetcode783.Minimum Distance Between BST Nodes二叉搜索树结点最小距离
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7136722.html
Copyright © 2011-2022 走看看