zoukankan      html  css  js  c++  java
  • 2016年团体程序设计天梯赛-模拟赛

    L2-1. 集合相似度

    stl set模板,以后复习可以看一下,当模板用了,去重很有用呀

    #include <cstdio>
    #include <set>
    using namespace std;
    set<int> s[50];
    int main(){
        //freopen("G:\input.in", "r", stdin);
        int n;
        scanf("%d", &n);
        for (int i = 0; i < n; ++i){
            int num, x;
            for (scanf("%d", &num); num; --num){
                scanf("%d", &x);
                s[i].insert(x);
            }
        }
        int k;
        for (scanf("%d", &k); k; --k){
            int a, b;
            scanf("%d%d", &a, &b);
            int counta = s[a - 1].size(), countb = s[b - 1].size();
            int cnt = 0;
            for (set<int>::iterator iter = s[a - 1].begin(); iter != s[a - 1].end(); ++iter){
                if (s[b - 1].find(*iter) != s[b - 1].end())
                    cnt++;
            }
            printf("%.2lf%%
    ", cnt*1.0/(counta+countb-cnt)*100);
        }
        return 0;
    }
    set模板

    L2-2. 树的遍历

    已知后序和中序输出层次遍历

    比如test的

    7
    2 3 1 5 7 6 4
    1 2 3 4 5 6 7
    思路:后序遍历按左右中的关系遍历,中序按左中右的关系遍历,所以后序遍历的最后一个4必然是整颗树的root,中序数组中的4前面的1 2 3必然是4(root)的左子树,1 2 3当作一个树,继续推导这颗树的root,(1 2 3)在后序数组可以确定root为1,在确定(1 2 3)树的左右子树..
    然后可以发现这是一个递归的过程,我的方法是递归的恢复原来的这颗树,至于层次遍历,我是用queue实现的
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <string>
    #include <map>
    #include <set>
    #include <algorithm>
    
    using namespace std;
    
    const int inf = 0x3f3f3f;
    const int MAXN = 3e1+10;
    
    using namespace std;
    
    
    struct tree{
        tree*l;
        tree*r;
        int d;
    };
    
    int L[MAXN],M[MAXN];
    map<int ,int >mp;
    
    tree* addnode(int d){
        tree*nt = (tree*)malloc(sizeof(tree));
        nt->d = d;
        nt->l = NULL;
        nt->r = NULL;
        return nt;
    }
    
    tree* dfs(int s,int e,int top){
        if(s>e)return NULL;
        if(s==e){
            return addnode(M[s]);
        }
        int mmax = 0,rootd;
        for(int i=s;i<=e;i++){
            if(mmax<mp[M[i]]){
                mmax = mp[M[i]];
                rootd = M[i];
            }
        }
        int mid;
        for(int i=s;i<=e;i++){
            if(M[i]==rootd){
                mid = i;
                break;
            }
        }
        tree*root = addnode(rootd);
        if(mid!=s)
            root->l = dfs(s,mid-1,2*top+1);
        if(mid!=e)
            root->r = dfs(mid+1,e,2*top+2);
        return root;
    }
    
    //queue实现层次遍历
    void print(tree*root){
        queue<tree*>Q;
        Q.push(root);
        while(!Q.empty()){
            tree *tf;
            tf = Q.front();
            Q.pop();
            if(tf!=root)cout<<" ";
            cout<<tf->d;
            if(tf->l!=NULL)Q.push(tf->l);
            if(tf->r!=NULL)Q.push(tf->r);
        }
        cout<<endl;
    
    }
    
    void del(tree*root){
        if(!root)return;
        del(root->l);
        del(root->r);
        free(root);
    }
    
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF){
            for(int i=0;i<n;i++){
                scanf("%d",&L[i]);
                mp[L[i]] = i;
            }
            for(int i=0;i<n;i++){
                scanf("%d",&M[i]);
            }
            tree*root = dfs(0,n-1,0);
            print(root);
            del(root);
        }
        return 0;
    }
    View Code

    L2-3. 家庭房产

    裸并查集

    0000~9999 节点都已经唯一确定,所以用一维数组做就好了,本来想用map<string,string>,输出方便一点,奈何gg了,不会改,输出了奇怪的东西,原来数组开小了,开了几个小时orz

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <stack>
    #include <string>
    #include <queue>
    #include <map>
    #include <set>
    #include <vector>
    #include <algorithm>
    
    const int inf = 0x3f3f3f;
    const int MAXN = 1e4+10;
    
    using namespace std;
    
    struct fy{
        int npcid;
        int faid;
        int maid;
        int k;
        int sid[5];
        int n;
        int s;
    };
    
    struct rel{
        int minid;
        int tol;
        int n;
        int s;
        double pern;
        double pers;
    };
    
    int father[MAXN];
    int mark[MAXN];
    fy a[MAXN];
    rel ans[MAXN],rec[MAXN];
    int n;
    
    void init(){
        for(int i=0;i<MAXN;i++){
            father[i] = i;
            mark[i] = 0;
        }
        memset(ans,0,sizeof(ans));
        memset(rec,0,sizeof(rec));
    }
    
    int  Find(int u){
        return u==father[u]?u:Find(father[u]);
    }
    
    void Union(int u,int v){
        father[u] = Find(u);
        father[v] = Find(v);
        if(father[u]>father[v])father[father[u]] = father[v];
        else father[father[v]] = father[u];
    }
    
    bool cmp(const rel &a,const rel &b){
        if(a.pers!=b.pers)
            return a.pers>b.pers;
        return a.minid<b.minid;
    }
    
    int main()
    {
        while(scanf("%d",&n)!=EOF){
            init();
           // cout<<Find(8888)<<endl;
            for(int i=0;i<n;i++){
                scanf("%d%d%d",&a[i].npcid,&a[i].faid,&a[i].maid);
                mark[a[i].npcid] = 1;
                if(a[i].faid!=-1){
                    Union(a[i].npcid,a[i].faid);
                    mark[a[i].faid] = 1;
                }
                if(a[i].maid!=-1){
                    Union(a[i].npcid,a[i].maid);
                    mark[a[i].maid] = 1;
                }
                scanf("%d",&a[i].k);
                for(int j=0;j<a[i].k;j++){
                    scanf("%d",&a[i].sid[j]);
                    if(a[i].sid[j]!=-1){
                        Union(a[i].npcid,a[i].sid[j]);
                        mark[a[i].sid[j]] = 1;
                    }
                }
                scanf("%d%d",&a[i].n,&a[i].s);
            }
            int fa;
            for(int i=0;i<n;i++){
                fa = Find(a[i].npcid);
                ans[fa].minid = fa;
                ans[fa].n += a[i].n;
                ans[fa].s += a[i].s;
            }
            for(int i=0;i<MAXN;i++){
                if(mark[i]){
                    fa = Find(i);
                    ans[fa].tol ++;
                }
            }
            int top = 0;
            for(int i=0;i<MAXN;i++){
                if(ans[i].tol){
                    rec[top] = ans[i];
                    rec[top].pern = rec[top].n*1.0/rec[top].tol;
                    rec[top].pers = rec[top].s*1.0/rec[top].tol;
                    top++;
                }
            }
            sort(rec,rec+top,cmp);
            cout<<top<<endl;
            for(int i=0;i<top;i++){
                if(rec[i].minid<10){
                    cout<<"000";
                }else if(rec[i].minid<100){
                    cout<<"00";
                }else if(rec[i].minid<1000){
                    cout<<"0";
                }
                printf("%d %d %.3lf %.3lf
    ",rec[i].minid,rec[i].tol,rec[i].pern,rec[i].pers);
            }
        }
        return 0;
    }
    并查集

    L2-4. 最长对称子串

    注意连续子串

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <cmath>
    #include <stack>
    #include <string>
    #include <queue>
    #include <vector>
    #include <map>
    #include <algorithm>
    
    const int inf = 0x3f3f3f;
    const int MAXN = 1e3+10;
    
    using namespace std;
    
    string ts1,ts2;
    int dp[2][MAXN];
    
    int main()
    {
        while(getline(cin,ts1)){
           // transform(ts1.begin(),ts1.end(),ts1.begin(),::tolower);
            int len = ts1.size();
            ts2 = ts1;
            reverse(ts2.begin(),ts2.end());
           // cout<<ts2<<endl;
            int mmax = 0;
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=len;i++){
                for(int j=1;j<=len;j++){
                    if(ts1[i-1]==ts2[j-1]){
                        dp[i%2][j] = dp[(i-1)%2][j-1]+1;
                        mmax = max(mmax,dp[i%2][j]);
                    }
                    else
                        dp[i%2][j] = 0;
                }
            }
            cout<<mmax<<endl;
        }
        //cout << "Hello world!" << endl;
        return 0;
    }
    连续lcs

    L3-1. 肿瘤诊断

    三维bfs

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <stack>
    #include <string>
    #include <queue>
    #include <map>
    #include <set>
    #include <algorithm>
    
    const int inf = 0x3f3f3f;
    const int X = 1286;
    const int Y = 128;
    const int Z = 60;
    
    using namespace std;
    struct ip{
        int x;
        int y;
        int z;
    };
    
    int mov[6][3]={{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}};
    int G[Z][X][Y];
    stack<ip>S;
    queue<ip>Q;
    int x,y,z,t;
    
    int check(int nx,int ny,int nz){
        if(nx<0||nx>=x||ny<0||ny>=y||nz<0||nz>=z||!G[nz][nx][ny])return 0;
        return 1;
    }
    
    int main()
    {
        while(scanf("%d%d%d%d",&x,&y,&z,&t)!=EOF){
            ip tmp;
            for(int i=0;i<z;i++){
                for(int j=0;j<x;j++){
                    for(int k=0;k<y;k++){
                        scanf("%d",&G[i][j][k]);
                        if(G[i][j][k]){
                            tmp.z = i;
                            tmp.x = j;
                            tmp.y = k;
                            S.push(tmp);
                        }
                    }
                }
            }
            ip tf;
            int cnt,sum=0;
            while(!S.empty()){
                tf = S.top();
                S.pop();
                cnt = 0;
    
                if(G[tf.z][tf.x][tf.y]){
                    cnt = 1;
                    G[tf.z][tf.x][tf.y] = 0;
                    Q.push(tf);
                    while(!Q.empty()){
                        tf = Q.front();
                        Q.pop();
                        int nx,ny,nz;
                        for(int i=0;i<6;i++){
                            nx = tf.x+mov[i][0];
                            ny = tf.y+mov[i][1];
                            nz = tf.z+mov[i][2];
                            if(check(nx,ny,nz)){
                                tmp.x = nx;
                                tmp.y = ny;
                                tmp.z = nz;
                                Q.push(tmp);
                                cnt++;
                                G[nz][nx][ny] = 0;
                            }
                        }
                    }
                }
    
                //cout<<cnt<<endl;
                if(cnt>=t)sum+=cnt;
            }
            cout<<sum<<endl;
        }
        //cout << "Hello world!" << endl;
        return 0;
    }
    stack+queue模拟

    L3-001. 凑零钱

    背包,达到背包容量,货物越多,每个货物的val越小,同理,零钱越多,也就越散,还有注意同样数量的的货物,存在val大的货物越多,也就会有越小可能的val货物,这样才能满足字典序输出的要求

    dp[i] = max(dp[i-val]+1,dp[i])

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <stack>
    #include <string>
    #include <queue>
    #include <vector>
    #include <map>
    #include <algorithm>
    
    const int inf = 0x3f3f3f;
    const int MAXN = 1e2+10;
    const int MAXM = 1e4+10;
    
    using namespace std;
    
    int dp[MAXN];
    int ans[MAXN];
    int a[MAXM];
    
    void print(int u){
        if(u==ans[u]){
            cout<<u;
            //cout<<"haha"<<endl;
            return ;
        }
        print(u-ans[u]);
        cout<<" "<<ans[u];
    }
    
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF){
            memset(dp,0,sizeof(dp));
            memset(ans,0,sizeof(ans));
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            sort(a+1,a+n+1);
    
            for(int i=1;i<=n;i++){
                for(int j=m;j>=a[i];j--){
                    if(dp[j-a[i]]||j==a[i]){
                        if(dp[j]<=dp[j-a[i]]+1){
                            dp[j] = dp[j-a[i]]+1;
                            ans[j] = a[i];
                        }
                    }
                }
            }
    
           /* for(int i=1;i<=m;i++){
                cout<<ans[i]<<" ";
            }
            cout<<"debug"<<endl;*/
           // cout<<"debug"<<endl;
            if(!ans[m]){
                cout<<"No Solution"<<endl;
                continue;
            }
            print(m);
            cout<<endl;
        }
        //cout << "Hello world!" << endl;
        return 0;
    }
    01背包
    
    

    L3-003. 社交集群

    还是裸并查集的题目,题目看错,wa了一次

    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <stack>
    #include <string>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    #include <algorithm>
    
    const int inf = 0x3f3f3f;
    const int MAXN = 1e3+10;
    
    using namespace std;
    
    int father[MAXN];
    int mark[MAXN];
    int ans[MAXN],rec[MAXN];
    int n,m;
    
    void init(){
        for(int i=0;i<MAXN;i++)
            father[i] = i;
        memset(ans,0,sizeof(ans));
        memset(rec,0,sizeof(rec));
        memset(mark,0,sizeof(mark));
    }
    
    int Find(int u){
        return u==father[u]?u:Find(father[u]);
    }
    
    void Union(int u,int v){
        father[u] = Find(u);
        father[v] = Find(v);
        father[father[u]] = father[v];
    }
    
    bool cmp(const int &a,const int &b){
        return a>b;
    }
    
    int main()
    {
        while(scanf("%d",&n)!=EOF){
            init();
            int v;
            for(int i=0;i<n;i++){
                scanf("%d:",&m);
                for(int j=0;j<m;j++){
                    scanf("%d",&v);
                    if(!mark[v]){
                        mark[v] = i+1;
                    }else{
                        Union(i+1,mark[v]);
                    }
                }
            }
    
            int fa;
            for(int i=1;i<=n;i++){
                fa = Find(i);
              // cout<<fa<<endl;
               // cout<<"debug"<<endl;
                ans[fa]++;
            }
            int top=0;
            for(int i=1;i<=n;i++){
                if(ans[i])
                    rec[top++] = ans[i];
            }
            cout<<top<<endl;
            sort(rec,rec+top,cmp);
            cout<<rec[0];
            for(int i=1;i<top;i++)
                cout<<" "<<rec[i];
            cout<<endl;
        }
        //cout << "Hello world!" << endl;
        return 0;
    }
    并查集
    在一个谎言的国度,沉默就是英雄
  • 相关阅读:
    将WinServers2019打造成家用系统
    WindowsServers2019上手体验
    【代码模板】不存在的NOIP2017
    NOIP2018初赛翻车总结
    【初赛】各种排序算法总结
    【Luogu1996】约瑟夫问题(模拟,解法汇总)
    【初赛】NOIP2018程序模板
    MongoDB
    非关系型数据库----MongoDB
    用Python来操作redis 以及在Django中使用redis
  • 原文地址:https://www.cnblogs.com/EdsonLin/p/5496700.html
Copyright © 2011-2022 走看看