zoukankan      html  css  js  c++  java
  • 北京大学ACM-ICPC竞赛训练暑期课

    全排列 (递归DFS)

    描述

    给定一个由不同的小写字母组成的字符串,输出这个字符串的所有全排列。 我们假设对于小写字母有'a' < 'b' < ... < 'y' < 'z',而且给定的字符串中的字母已经按照从小到大的顺序排列。

    输入输入只有一行,是一个由不同的小写字母组成的字符串,已知字符串的长度在1到6之间。输出输出这个字符串的所有排列方式,每行一个排列。要求字母序比较小的排列在前面。字母序如下定义:

    已知S = s1s2...sk , T = t1t2...tk,则S < T 等价于,存在p (1 <= p <= k),使得
    s1 = t1, s2 = t2, ..., sp - 1 = tp - 1, sp < tp成立。样例输入

    abc

    样例输出

    abc
    acb
    bac
    bca
    cab
    cba
    #include <bits/stdc++.h>
    using namespace std;
    string str,sub;
    int a[50000+5],cnt=0,n;
    string ch[720];
    void dfs(int k,string &sub)
    {
    
        //cout<<k<<endl;
        if(k==n)
        {
            cout<<sub<<endl;
            return ;
        }
        for(int i=0;i<n;i++)
        {
            if(!a[i])
            {
                string xx;
                xx=sub;
                sub+=str[i];
                a[i]=1;cnt++;
                dfs(cnt,sub);
                a[i]=0;cnt--;
                sub=xx;
            }
        }
    }
    int main()
    {
        int m,l,r;
        cin>>str;
        memset(a,0,sizeof(a));
        n= str.size();
        sub="";
        dfs(cnt,sub);
        return 0;
    
    }
    View Code

    冰阔落 I

    描述

    老王喜欢喝冰阔落。

    初始时刻,桌面上有n杯阔落,编号为1到n。老王总想把其中一杯阔落倒到另一杯中,这样他一次性就能喝很多很多阔落,假设杯子的容量是足够大的。

    有m 次操作,每次操作包含两个整数x与y。

    若原始编号为x 的阔落与原始编号为y的阔落已经在同一杯,请输出"Yes";否则,我们将原始编号为y 所在杯子的所有阔落,倒往原始编号为x 所在的杯子,并输出"No"。

    最后,老王想知道哪些杯子有冰阔落。

     

    输入有多组测试数据,少于 5 组。
    每组测试数据,第一行两个整数 n, m (n, m<=50000)。接下来 m 行,每行两个整数 x, y (1<=x, y<=n)。
    输出每组测试数据,前 m 行输出 "Yes" 或者 "No"。
    第 m+1 行输出一个整数,表示有阔落的杯子数量。
    第 m+2 行有若干个整数,从小到大输出这些杯子的编号。
    样例输入

    3 2
    1 2
    2 1
    4 2
    1 2
    4 3
    

    样例输出

    No
    Yes
    2
    1 3 
    No
    No
    2
    1 4


    #include <bits/stdc++.h>
    using namespace std;
    string str;
    int a[50000+5],cnt;
    int root(int x)
    {
        if(a[x]==x) return x;
        return root(a[x]);
    }
    void find(int l,int r)
    {
        int ll=root(l),rr=root(r);
        if(ll==rr)
        {
            printf("Yes
    ");
            //cout<<"Yes"<<endl;
        }
        else
        {
            a[rr] =ll;
            cnt--;
            //cout<<"No"<<endl;
            printf("No
    ");
        }
    }
    int main()
    {
        int m,n,l,r;
        while(scanf("%d %d",&n,&m)!=EOF)
        {
            cnt=n;
            for(int i=1;i<=n;i++)
            {
                a[i]=i;
            }
            for(int i=1;i<=m;i++)
            {
                scanf("%d %d",&l,&r);
                //cin>>l>>r;
                find(l,r);
            }
            printf("%d
    ",cnt);
            //cout<<cnt<<endl;
            for(int i=1;i<=n;i++)
                if(a[i]==i) printf("%d ",i);//cout<<i<<" ";
            //cout<<endl;
            printf("
    ");
        }
        return 0;
    
    }
    View Code

    开餐馆

    描述

    北大信息学院的同学小明毕业之后打算创业开餐馆.现在共有n 个地点可供选择。小明打算从中选择合适的位置开设一些餐馆。这 n 个地点排列在同一条直线上。我们用一个整数序列m1, m2, ... mn 来表示他们的相对位置。由于地段关系,开餐馆的利润会有所不同。我们用pi 表示在mi 处开餐馆的利润。为了避免自己的餐馆的内部竞争,餐馆之间的距离必须大于k。请你帮助小明选择一个总利润最大的方案。

    输入标准的输入包含若干组测试数据。输入第一行是整数T (1 <= T <= 1000) ,表明有T组测试数据。紧接着有T组连续的测试。每组测试数据有3行,
    第1行:地点总数 n (n < 100), 距离限制 k (k > 0 && k < 1000).
    第2行:n 个地点的位置m1 , m2, ... mn ( 1000000 > mi > 0 且为整数,升序排列)
    第3行:n 个地点的餐馆利润p1 , p2, ... pn ( 1000 > pi > 0 且为整数)输出对于每组测试数据可能的最大利润样例输入

    2
    3 11
    1 2 15
    10 2 30
    3 16
    1 2 15
    10 2 30

    样例输出

    40
    30

    #include <bits/stdc++.h>
    using namespace std;
    int dp[100+5];
    struct node 
    {
        int v,h;
    } no[100+5];
    int main()
    {
        int t,n,m;
        cin>>t;
        while(t--)
        {
            cin>>n>>m;
            for(int i=1;i<=n;i++)
                scanf("%d",&no[i].v );
            for(int i=1;i<=n;i++)
                scanf("%d",&no[i].h );
            if(m>no[n].v)
            {
                int mx=-1000;
                for(int i=1;i<=n;i++)
                    mx=max(no[i].h,mx);
                printf("%d
    ",mx);
            }
            else
            {
                for(int i=1;i<=n;i++)
                {
                    dp[i] = no[i].h;
                    int mx = no[i].v , mk = no[i].h ;    
                    for(int j=1;j<i;j++)
                    {
                        if( no[i].v - no[ j ].v > m )
                        {
                            dp[ i ] = max( dp[i] ,dp[j] + mk );
                        }
                            
                    }
                }
                cout<<*max_element(dp+1,dp+n+1)<<endl;    
            }
            
        }
        return 0;
    }
    View Code

    输出前k大的数

    描述

    给定一个数组,统计前k大的数并且把这k个数从大到小输出。

    输入第一行包含一个整数n,表示数组的大小。n < 100000。
    第二行包含n个整数,表示数组的元素,整数之间以一个空格分开。每个整数的绝对值不超过100000000。
    第三行包含一个整数k。k < n。输出从大到小输出前k大的数,每个数一行。样例输入

    10
    4 5 6 9 8 7 1 2 3 0
    5

    样例输出

    9
    8
    7
    6
    5

    #include<bits/stdc++.h>
    #include<stdio.h>
    #include<iostream>
    using namespace std;
    int n,k;
    int a[100000+5];
    void find(int l,int r,int ans)
    {
        if(l>=r) return ;
        int ll=l,rr=r;
        while(l!=r)
        {
            while(l<r && a[l]<=a[r]) r--;
            swap(a[l],a[r]);
            while(l<r && a[l]<=a[r]) l++;
            swap(a[l],a[r]);
        }
        if(rr-l+1 == ans) return ;
        rr-l+1 < ans  ? find(ll,l-1,ans-(rr-l+1))  :find(l+1,rr,ans);
    }
    int main()
    {
        cin>>n;
        for(int i=0;i<n;i++)    cin>>a[i];
        cin>>k;
        find(0,n-1,k);
        sort(a+n-k,a+n);
        for(int t=n-1;t>=n-k;t--)
            cout<<a[t]<<endl;    
        return 0;
    }
    View Code

    滑雪 

    描述Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长的滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子

     1  2  3  4 5
    16 17 18 19 6
    15 24 25 20 7
    14 23 22 21 8
    13 12 11 10 9


    一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。输入输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。输出输出最长区域的长度。样例输入

    5 5
    1 2 3 4 5
    16 17 18 19 6
    15 24 25 20 7
    14 23 22 21 8
    13 12 11 10 9
    

    样例输出

    25
    #include <bits/stdc++.h>
    using namespace std;
    
    int dir[4][2]={-1,0,0,1,1,0,0,-1};
    int a[101][101],len[101][101];
    int n,m;
    int dfs(int x,int y)
    {
        if(len[x][y]) return len[x][y];
        int mx=0,s;
        for(int i=0;i<4;i++)
        {
            int nx=x+dir[i][0],ny=y+dir[i][1];
            if(nx>=0 && nx<n && ny>=0 && ny<m && a[nx][ny] < a[x][y])
            {
                s=dfs(nx,ny);
                if(s>mx)
                    mx=s;
            }
        }
        
        return len[x][y] = mx+1;
    }
    int main()
    {
        int mx=-1;
        cin>>n>>m;
        memset(len,0,sizeof(len));
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                cin>>a[i][j];
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(dfs(i,j) > mx)
                    mx=len[i][j];
        cout<<mx<<endl;
        return 0;
    }
    View Code
    所遇皆星河
  • 相关阅读:
    extract numberic from text
    str.rfind("//")
    solr入门心得
    深挖洞,广积粮,缓称王
    ubuntu 查看文件夹大小

    关于托运
    iconv转换文件编码
    小毛小毛你的心态
    广积粮,高筑墙,缓称王
  • 原文地址:https://www.cnblogs.com/Shallow-dream/p/13769726.html
Copyright © 2011-2022 走看看