• uva 10905 Children's Game


    继续复习基础算法

    题意,给n个数字,将它们重新排序得到一个最大的数字,好像给出123 456 789 拼为 789456123 最大

    这题可以算是一个排序题,不过排序的规则有讲究

    如果想用字典序排序,显然错了,好像999123 999 , 按字典序排序999123在前面,得到的数字为999123999 , 显然没有不够999999123 大

    有两种不同的思想解这题

    1.处理前缀的问题,上面那个例子,999是999123的前缀,这种比较不能简单以字典序比较,而是应该用一种“环”的思想去比较,即999比完了,A串到了1,B串应该轮回来变为9,。也就是A串和B串都已这种环的方式去计较,知道第一个不相同的字符出现则跳出。

    会不会跳不出来呢,是有的,好像123123 123 , 这样子用环来比较是没有跳出的一天的,我就是忘记了判这个TLE了一次 , 像这种恶心的循环串,会发现把A或B放前面都无所谓,所以我们要用环来判的时候,还要约定一个判断次数,达到了一定的判断次数,如果还没有找到不同的字符,就要跳出了,那么判断次数是多少,应该是两个串长度的LCM。这个很容易想,如果在LCM此比较了都找不到不同的,那么将重新回到刚开始比较的时候

    2.一种更简单的思想,假设我们有n个串,排序了,得到了最优序列,那么我们任意找两块,A和B,我们试图去交换这两块的位置,结果是什么,结果是一定得到的数字一定 <= 最大值 , 这用反证就能证明,如果交换了能更大,那我们早就交换了。所以在排序的时候,比较这个步骤就看 A+B > B+A 是否成立,成立的话A在前面,其中+是表示两个串的连接,在整个排序过程中,都以这种规则来排,排完后就是最优的

    算法1

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #define N 55
    #define LEN 1100
    
    struct word
    {
       char s[LEN];
    }a[N];
    int n;
    
    int gcd(int x ,int y)
    {
       return y == 0 ? x : gcd(y , x%y);
    }
    
    int lcm(int x ,int y)
    {
       return x / gcd(x,y) * y;
    }
    
    bool cmp(struct word p , struct word q)
    {
       int lenp = strlen(p.s);
       int lenq = strlen(q.s);
       if(lenp == lenq)
          return strcmp(p.s , q.s) > 0 ;
       else
       {
          int len = lcm(lenp ,lenq);
          int i = 0 , j = 0 , c=0;
          while(p.s[i] == q.s[j] && c<len)
          {
             i=(i+1)%lenp;
             j=(j+1)%lenq;
             c++;
          }
          return p.s[i] > q.s[j];
       }
    }
    
    int main()
    {
       while(scanf("%d",&n)!=EOF && n)
       {
          for(int i=0; i<n; i++)
             scanf("%s",a[i].s);
          sort(a,a+n,cmp);
          for(int i=0; i<n; i++)
             printf("%s",a[i].s);
          printf("\n");
       }
       return 0;
    }

    算法2

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <algorithm>
    using namespace std;
    #define N 55
    
    string word[N];
    int n;
    
    bool cmp(string a ,string b)
    {
       return a+b > b+a;
    }
    
    int main()
    {
       while(scanf("%d",&n)!=EOF && n)
       {
          for(int i=0; i<n; i++)
             cin >> word[i];
          sort(word , word+n , cmp);
          for(int i=0; i<n; i++)
             cout << word[i];
          cout << endl;
       }
       return 0;
    }
  • 相关阅读:
    切割窗口url
    软键盘弹出底部被顶上去
    C语言字符串处理标准库函数的源码(转)
    slapd配置文件详述
    OPENLDAP安装配置方法
    const成员函数
    OPENLDAP概述
    当前比较有名的Xml数据库
    『转』使用 Scalable Vector Graphics 为 ASP.NET 构建基于 XML 的灵活、轻量的图像
    SqlCommand_ExecuteNonQuery 方法返回值为1的解释
  • 原文地址:https://www.cnblogs.com/scau20110726/p/3039236.html
Copyright © 2020-2023  润新知