• 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
  • 相关阅读:
    Web开发四大作用域(转)
    jsp与servlet(转)
    使用jsp,tomcat实现用户登录注册留言的代码
    java环境变量的配置
    JSP 九大内置对象(转)
    http协议头文件的控制信息(转)
    javaScript实现图片滚动及一个普通图片轮播的代码
    javaScript显示实时时间输出
    javaScript判断输入框是否为空
    1072 威佐夫游戏
  • 原文地址:https://www.cnblogs.com/lyzuikeai/p/7136722.html
Copyright © 2020-2023  润新知