zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Windows Store App 主题动画
    Windows Store App 过渡动画
    Windows Store App 控件动画
    Windows Store App 近期访问列表
    Windows Store App 文件选取器
    Windows Store App 访问应用内部文件
    Windows Store App 用户库文件分组
    Windows Store App 获取文件及文件夹列表
    Windows Store App 用户库文件夹操作
    Windows Store App 用户库文件操作
  • 原文地址:https://www.cnblogs.com/scau20110726/p/3039236.html
Copyright © 2011-2022 走看看