zoukankan      html  css  js  c++  java
  • 2017-10-15 NOIP模拟赛

     Stack

    #include<iostream>
    #include<cstdio>
    #define mod 7
    using namespace std;
    int f[1010][1010],n;
    int main(){
        freopen("stack.in","r",stdin);freopen("stack.out","w",stdout);
        scanf("%d",&n);
        for(int i=0;i<=n;i++)
            for(int j=0;j<=i;j++){
                if(j)f[i][j]=f[i-1][j]+f[i][j-1];
                else f[i][j]=1;
                while(f[i][j]>=mod)f[i][j]-=mod;
            }
        printf("%d",f[n][n]);
        return 0;
    }
    100分 卡特兰数求第n项取模

    Cube

    /*
        记录每个点下面有多少元素top[i],他所在并查集的大小,每次移动操作就把移动后在上面的那部分中所有的点的top加上它移动到的病茶几的大小,修改复杂度很高,查询是O(1)的
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 30010
    using namespace std;
    int p,fa[maxn],sz[maxn],top[maxn];
    char ch[5];
    int find(int x){
        if(fa[x]==x)return fa[x];
        return fa[x]=find(fa[x]);
    }
    int main(){
        //freopen("Cola.txt","r",stdin);
        freopen("cube.in","r",stdin);freopen("cube.out","w",stdout);
        scanf("%d",&p);
        int n=0;
        for(int i=1;i<=30000;i++)fa[i]=i,sz[i]=1;
        while(p--){
            scanf("%s",ch);
            int x,y;
            if(ch[0]=='M'){
                scanf("%d%d",&x,&y);
                n=max(n,max(x,y));
                int f1=find(x),f2=find(y);
                if(f1!=f2){
                    for(int i=1;i<=n;i++){
                        if(find(i)==f1){
                            top[i]+=sz[f2];
                        }
                    }
                    fa[f1]=f2;
                    sz[f2]+=sz[f1];
                    sz[f1]=0;
                }
                
            }
            else{
                scanf("%d",&x);
                n=max(n,x);
                printf("%d
    ",top[x]);
            }
        }
    }
    70分 暴力并查集
    #include<iostream>
    #include<cstdio>
    #define maxn 30010
    using namespace std;
    int p,cnt[maxn],sum[maxn],fa[maxn];
    char s[4];
    int find(int x){
        if(x==fa[x])return fa[x];
        int f=fa[x];
        fa[x]=find(fa[x]);
        cnt[x]+=cnt[f];
        return fa[x];
    }
    void merge(int x,int y){
        fa[y]=x;
        cnt[y]+=sum[x];
        sum[x]+=sum[y];
        sum[y]=0;
    }
    int main(){
        freopen("cube.in","r",stdin);freopen("cube.out","w",stdout);
        for(int i=1;i<=30000;i++)fa[i]=i,sum[i]=1;
        scanf("%d",&p);
        while(p--){
            scanf("%s",s);
            int x,y;
            if(s[0]=='M'){
                scanf("%d%d",&x,&y);
                merge(find(x),find(y));
            }
            else {
                scanf("%d",&x);
                printf("%d
    ",sum[find(x)]-cnt[x]-1);
            }
        }
    }
    100分 带权并查集

    Zuma

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    #include<queue>
    using namespace std;
    map<string,bool>vis;
    string s,snow;
    struct node{
        string s;
        int step;
    }cur,nxt;
    queue<node>q;
    void down(){
        string pre=snow;
        snow="";
        for(int i=0;i<pre.length();){
            while(pre[i]=='2'&&i<pre.length())i++;
            snow=snow+pre[i];i++;
        }
    }
    void updata(){
        string pre=snow;
        bool flag=0;
        for(int i=0;i<pre.length();i++){
            if(pre[i]==pre[i-1]&&pre[i]==pre[i+1])flag=1,snow[i]=snow[i-1]=snow[i+1]='2';
        }
        if(flag){
            down();
            updata();
        }
    }
    int main(){
        //freopen("Cola.txt","r",stdin);
        freopen("zuma.in","r",stdin);freopen("zuma.out","w",stdout);
        cin>>s;
        vis[s]=1;
        cur.s=s;cur.step=0;
        //cout<<s<<endl;
        bool flag=0;
        int n1=0,n0=0;
        for(int i=1;i<s.length();i++){
            if(s[i]==s[i-1]){
                flag=1;break;
            }
            if(s[i]=='0')n0++;
            if(s[i]=='1')n1++;
        }
        if(flag==0){
            int ans=0;
            if(s[0]=='0')n0++;
            if(s[0]=='1')n1++;
            if(n1%2==0&&n0%2==0&&n1==n0){
                ans=2+(n1/2)+((n0-2)/2)+2;
                printf("%d",ans);
                return 0;
            }
            if(n1%2==1&&n0%2==1&&n1==n0){
                ans=4+((n1-1)/2)+((n0-1)/2);
                printf("%d",ans);
                return 0;
            }
            if(n1<n0)swap(n1,n0);
            if(n1%2==1&&n0==n1-1){
                ans=2+((n1-1)/2)+(n0/2);
                printf("%d",ans);
                return 0;
            }
            if(n1%2==0&&n0==n1-1){
                ans=2+(n1/2)+((n0-1)/2);
                printf("%d",ans);
                return 0;
            }
        }
        q.push(cur);
        while(!q.empty()){
            cur=q.front();q.pop();
            int len=cur.s.length();
            //cout<<cur.s<<endl;
            if(len==0){printf("%d",cur.step);return 0;}
            for(int i=0;i<=len;i++){//在第i个前面插 
                snow="";
                snow=snow+cur.s.substr(0,max(0,i));
                snow=snow+"0";
                snow=snow+cur.s.substr(i,len-i);
                string now=snow;
                updata();
                if(!vis[snow]){
                    vis[snow]=1;
                    nxt.s=snow;nxt.step=cur.step+1;
                    q.push(nxt);
                    if(nxt.s.length()==1&&nxt.s[0]!='0'&&nxt.s[0]!='1'){printf("%d",nxt.step);return 0;}
                }
                //cout<<snow<<endl;
                
                snow=now;
                snow[i]='1';
                updata();
                if(!vis[snow]){
                    vis[snow]=1;
                    nxt.s=snow;nxt.step=cur.step+1;
                    q.push(nxt);
                    if(nxt.s.length()==1&&nxt.s[0]!='0'&&nxt.s[0]!='1'){printf("%d",nxt.step);return 0;}
                }
                //cout<<snow<<endl;
            }
        }
        fclose(stdin);fclose(stdout);
        return 0;
    }
    65分 宽搜
    /*
        区间dp,情况有些多需要讨论
        首先连续相同的颜色为了方便要合并,记录每个块的颜色,就可以dp了
        dp[l][r]表示合并这段区间的最小步数,分几种情况
        这段区间是奇数(为了避免区间长度为2的情况)
        1. color[l]==color[r] && tot[l]+tot[r]==2  --> dp[l][r] 可从 dp[l+1][r-1]+1 转移过来。
        2. color[l]==color[r] && tot[l]+tot[r]>2   --> dp[l][r] 可从 dp[l+1][r-1] 转移过来。
        3. color[l]==color[k]==color[r](k∈(l,r) && [l,k],[k,r] 为奇数)  -->可从dp[l+1][k-1]+dp[k+1][r-1]转移过来。
        这段区间是偶数
        普通的转移 dp[l][r] =min(dp[l][r] , dp[l][k]+dp[k+1][r]);
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 257
    using namespace std;
    int dp[maxn][maxn],col[maxn],a[maxn];
    char s[maxn];
    int n,m,ans;
    int main(){
        freopen("zuma.in","r",stdin);freopen("zuma.out","w",stdout);
        scanf("%s",s);n=strlen(s);
        a[1]=1;m=1;
        for(int i=1;i<n;i++){
            if(s[i]==s[i-1]){
                col[m]=s[i]-'0';
                a[m]++;
            }
            else {
                a[++m]=1;
                col[m]=s[i]-'0';
            }
        }
        for(int len=0;len<=m;len++){
            for(int i=1;i<=m;i++){
                int j=i+len;
                if(j>=1&&j<=m){
                    dp[i][j]=2*n;
                    if(len==0)dp[i][j]=3-a[i];
                    else {
                        for(int k=i;k<j;k++)
                            dp[i][j]=min(dp[i][k]+dp[k+1][j],dp[i][j]);
                        if((j-i)%2==0){
                            if(a[i]+a[j]==2){
                                if(col[i]==col[j])
                                    dp[i][j]=min(dp[i][j],dp[i+1][j-1]+1);
                            }
                            else
                                if(col[i]==col[j])
                                    dp[i][j]=min(dp[i][j],dp[i+1][j-1]);
                            if(a[i]+a[j]<4)
                                for(int k=i+2;k<j;k+=2)
                                    if(a[k]==1)dp[i][j]=min(dp[i+1][k-1]+dp[k+1][j-1],dp[i][j]);
                        }
                    }
                }
            }
        }
        printf("%d
    ",dp[1][m]);
        return 0;
    }
    100分 区间dp
  • 相关阅读:
    Keras猫狗大战四:数据增强+添加dropout层,精度达83%
    Keras猫狗大战三:加载模型,预测目录中图片,画混淆矩阵
    左边列表多选可以批量移动到右边列表,右边列表页可以批量移动到左边列表,可以实现前端自动搜索 ajax 传递List
    两个list框联动-转载
    mybatis
    lambda
    sprint 单元测试
    java项目部署测试服务器二级域名解决方案
    java cookie 单点登录和登录拦截器 从实现到原理
    redis 概述和阿里云redis搭建和java后台获取
  • 原文地址:https://www.cnblogs.com/thmyl/p/7670269.html
Copyright © 2011-2022 走看看