zoukankan      html  css  js  c++  java
  • ACdream群训练赛(46)

    A.Seinfeld

    http://acm.hdu.edu.cn/showproblem.php?pid=3351

    用num来标记次数,用len来表示 { 的个数 从前开始遍历字符串,如果是 { 就不配对 ,len++,如果是 } 且如果len不为0就len--,在此情况下如果len为零了,就只能将此字符变成 { ,那么num++;遍历完了,如果len不为0就说明剩下了 { 没有配对 此时只需要 num+=len/2即可;

    View Code
    #include <fstream>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <iomanip>
    #include <iomanip>
    #include <climits>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <list>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <string>
    #include <cstring>
    
    using namespace std;
    
    int n0,n1,n2,n3,n4;
    
    int main()
    {
        string s;
        int i,k,num,len;
        for(k=1;;k++)
        {
            cin>>s;
            if(s[0]=='-')
            break;
            num=0;
            len=0;
            for(i=0;i<s.size();i++)
            {
                if(s[i]=='{')
                len++;
                else
                {
                    if(len)
                    len--;
                    else
                    {
                        num++;
                        s[i]='{';
                        len=1;
                    }
                }
            }
            if(len>0)
            num+=len/2;
            cout<<k<<'.'<<' '<<num<<endl;
        }
        return 0;
    }

    B.Tiles of Tetris, NOT!

    http://acm.hdu.edu.cn/showproblem.php?pid=3352

    就是问最少用多少个矩形能拼成一个面积最小的正方形。num=最小公倍数/a*最小公倍数/b。

    View Code
    #include <fstream>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <iomanip>
    #include <iomanip>
    #include <climits>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <list>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <string>
    #include <cstring>
    
    using namespace std;
    
    int gcd(int a,int b)
    {
        int c;
        if(a==0)  return b;
        while(b!=0) c=b,b=a%b,a=c;
        return a;
    }
    int main()
    {
        long long a,b;
        while(cin>>a>>b)
        {
            if(a==0&&b==0)  break;
            int c=gcd(a,b);
            long long d=a*b/c/c;
            cout<<d<<endl;
        }
        return 0;
    }

    C.Not So Flat After All

    http://acm.hdu.edu.cn/showproblem.php?pid=3353

    分别把两个数分解质因数为p1^a1*p2^a2......的形式。维度就是两个数需要的所有素数,距离就是两个数所有质因数的a1、a2...的差的和。

    View Code
    #include <fstream>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <iomanip>
    #include <iomanip>
    #include <climits>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <list>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <string>
    #include <cstring>
    
    using namespace std;
    
    #define MAX 1000000
    
    int noprime[MAX];
    int pp[2][MAX];
    int numm[MAX];       //出现几个素数
    int numnum;
    int vis[MAX];
    int b[2];
    
    int Max(int a,int b)    {   return a>b?a:b;  }
    int Min(int a,int b)    {   return a<b?a:b;  }
    
    void Prime(int n)        //筛法求素数
    {
        int k;
        noprime[0]=noprime[1]=1;
        noprime[2]=0;
        for (int i=2;i<n;i++)
            if (!noprime[i])
            {
                k=i;
                while(k+i<n)
                {
                    k=k+i;
                    noprime[k]=1;
                }
            }
    }
    
    void find_prime_factor(int n)
    {
        int k=b[n];
        for (int i=2;i<=k;i++)
            if (!noprime[i])
            {
                if (k%i==0)
                {
                    if (!vis[i])
                    {
                        vis[i]=numnum+1;
                        numm[numnum]=i;
                        numnum++;
                    }
                    while (k%i==0)
                    {
                        k/=i;
                        pp[n][vis[i]-1]++;
                    }
    
                }
            }
        return;
    }
    
    int main()
    {
        int caseo=1;
        Prime(1000000);
        while(cin>>b[0]>>b[1])
        {
            if (b[0]==0 && b[1]==0)
                return 0;
            memset(pp,0,sizeof(pp));
            memset(numm,0,sizeof(numm));
            memset(vis,0,sizeof(vis));
            numnum=0;
            find_prime_factor(0);
            find_prime_factor(1);
            cout<<caseo++<<". "<<numnum<<":";
            int ans=0;
            for (int i=0;i<numnum;i++)
            {
                ans+=abs(pp[0][i]-pp[1][i]);
            }
            cout<<ans<<endl;
        }
    
    
        return 0;
    }

    D.Probability One

    http://acm.hdu.edu.cn/showproblem.php?pid=3354

    简单题,模拟即可。

    View Code
    #include <fstream>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <iomanip>
    #include <iomanip>
    #include <climits>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <list>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <string>
    #include <cstring>
    
    using namespace std;
    
    int n0,n1,n2,n3,n4;
    
    int main()
    {
        int caseo=1;
        while(cin>>n0,n0)
        {
            n1=n0*3;
            if (n1%2==1)
                n2=(n1+1)/2;
            else
                n2=n1/2;
            n3=3*n2;
            n4=n3/9;
            if (n1%2==1)
            {
                string s="odd";
                cout<<caseo++<<". "<<s<<" "<<n4<<endl;
            }
            else
            {
                string s="even";
                cout<<caseo++<<". "<<s<<" "<<n4<<endl;
            }
    
        }
    
    
        return 0;
    }

    G.Stock Chase(难)

    http://acm.hdu.edu.cn/showproblem.php?pid=3357

    // 【题意】
    // 有N个公司,A公司可以买B公司的股票
    // B公司可以买C公司的股票,如此A公司会间接持有C公司的股票
    // 只要A公司直接或者间接持有了X公司的股票,X公司就不能购买A公司的股票,这种操作非法
    // 按照时间顺序给出T次购买请求,问有多少次非法的购买请求会被回绝

    // 【思路】
    // 传递闭包
    // 每个query后加入一条边,计算新的传递闭包
    // 由于每次query前,G都是一个传递闭包,所以可以直接看是否有逆向弧来判断是否query合法

    // 时间复杂度肉眼看是O(T*N*N),T是查询次数,N是节点数
    // 理论上铁超时,但是实际上G很快会达到一种“饱和”的状态,大部分的query都是马上得到结果

    View Code
    #include <fstream>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <iomanip>
    #include <iomanip>
    #include <climits>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <list>
    #include <set>
    #include <algorithm>
    #include <string>
    #include <cstring>
    
    using namespace std;
    
    #define MAXN       235
    
    bool conn[MAXN][MAXN];
    std::vector<int> vconn[MAXN];
    int N, T;
    
    int main()
    {
           int kase = 1;
    
           int i, k;
           int v;
           for (i = 1; i <= MAXN; i++)
                  vconn[i].reserve(MAXN);
    
           while (scanf("%d %d", &N, &T), N || T) {
                  memset(conn, 0, sizeof(conn));
                  for (i = 1; i <= N; i++) {
                         // 注意有自己到自己的弧,这样做是为了方便算传递闭包,算之前应该对i==i做特判
                         vconn[i].resize(0);
                         vconn[i].push_back(i);
                         conn[i][i] = true;
                  }
    
                  int a, b;
                  int res = 0;
                  while (T--) {
                         scanf("%d %d", &a, &b);
                         if (a == b || conn[b][a]) {
                                res ++;
                                continue;
                         }
    
                         if (conn[a][b])
                                continue;
    
                         for (i = 1; i <= N; i++) {
                                // 没有到a的弧或者已经有到b的弧
                                if (!conn[i][a] || conn[i][b])
                                       continue;
    
                                // 到a有弧,到b没弧
                                for (k = vconn[b].size()-1; k >= 0; k--) {
                                       v = vconn[b][k];
                                       if (conn[i][v])
                                              continue;
    
                                       conn[i][v] = true;
                                       vconn[i].push_back(v);
                                }
                         }
                  }
    
                  printf("%d. %d\n", kase++, res);
           }
    
           return 0;
    }

    K.Hex-a-bonacci

    http://lightoj.com/volume_showproblem.php?problem=1006

    这道题挺有意思的。如果直接复制代码(刚开始就以为是这样一道用来搞笑的题。。。)递归fn重复计算太多要超时,把它放到数组里存起来就好了

    View Code
    #include <fstream>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <iomanip>
    #include <iomanip>
    #include <climits>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <list>
    #include <set>
    #include <map>
    #include <algorithm>
    #include <string>
    #include <cstring>
    
    using namespace std;
    
    int a, b, c, d, e, f;
    int ffn[10005];
    int fn( int n ) {
        if( n == 0 ) return a;
        if( n == 1 ) return b;
        if( n == 2 ) return c;
        if( n == 3 ) return d;
        if( n == 4 ) return e;
        if( n == 5 ) return f;
        return( ffn[n-1] + ffn[n-2] + ffn[n-3] + ffn[n-4] + ffn[n-5] + ffn[n-6] );
    }
    int main() {
        int n, caseno = 0, cases;
        scanf("%d", &cases);
        while( cases-- ) {
            scanf("%d %d %d %d %d %d %d", &a, &b, &c, &d, &e, &f, &n);
            for (int i=0;i<=n;i++)
                ffn[i]=fn(i)% 10000007;
            printf("Case %d: %d\n", ++caseno, ffn[n] % 10000007);
        }
        return 0;
    }

     

    举杯独醉,饮罢飞雪,茫然又一年岁。 ------AbandonZHANG
  • 相关阅读:

    泛型
    特性
    2.Linux基础入门
    1.Linux介绍及系统安装
    php十七种设计模式适用场合总结
    转载zendframework 插件方式
    常用的Jquery代码片段,没事的时候研究一下
    Zend Framework1.9 模块化搭建
    PHP的设计模式总结命令链模式
  • 原文地址:https://www.cnblogs.com/AbandonZHANG/p/2613718.html
Copyright © 2011-2022 走看看