連接整數

【問題描述】

  設有n(n<=20)個正整數,將他們連接成一排,組成一個最大的多位整數。

  例如n=3時,3個整數13,312,343,連接成的最大整數爲34331213。

  又如:n=4時,4個整數7,13,4,246連成的最大整數爲7424613。

【輸入格式】

  第1行一個整數n,第2行n個整數數

【輸出格式】

  連接成的多位數。

【輸入樣例】

4
7 13 4 246

【輸出樣例】

7424613

【數據範圍】

n<=20

題意:很簡單,就是給你一些正整數,要求你把這些正整數重新組合成新的一個整數,要求這個新的整數儘量大。
算法:貪心(排序有點難想啊);
這個題看起來並不難,可能很多人覺得,將每個整數讀入一個字符串數組。然後通過比較字符串的大小排序就能確定輸出整數的順序。我也是這樣做的,結果只得了75分。錯了一組數據:
6
321 32 407 135 13 217
正確答案 4073232121713513
而我的輸出 4073213221713513 321和32的順序倒了
所以這樣想是有漏洞的,因爲可能存在一個串的前綴和另一個相等的情況,在這種情況下,顯然兩者中更長的串的ASCII碼更大,然而卻不一定要選更長的串。
因爲最後答案整數的位數是定了的,如果把前面ASCII碼大的串先加入,由於調整位置時原數字不能拆分,所以會佔更多的高位。而這些多出來高位的值可能還不如加入小的串後前面幾位的值。
整理了一下老師講的和網上的算法:
正確排序1:如果一個字符串是第二個字符串的前綴的話,則將長串與第一個字符串相同的部分截去,將剩下的繼續比較,當出現有字串長度爲0的時候特殊處理。(見代碼1)
正確排序2:設兩個待比較的字符串爲s1,s2,那麼其實要最優只需要比較strcat(s1,s2)和strcat(s2,s1)即可。(代碼2)

<代碼1>

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
#include<set>
#include<cstdlib>
#define maxn 25
using namespace std;
int n;
string num[maxn];

bool cmp(const string& s1, const string& s2)//比較s1和s2,在相同位時如果某個字符串數字較大就把它排在前 
{ 
  if(s1.size()==0) return false;//s1不存在數字就排在後 
  if(s2.size()==0) return true;//s2不存在數字就把s1排前面 

  int minsz=min(s1.size(),s2.size()); 

  if(strncmp(s1.c_str(),s2.c_str(),minsz)==0)
  { 
    if(minsz==s1.size())
    { 
      return cmp(s1,s2.substr(minsz)); 
    } 
    else 
    { 
      return cmp(s1.substr(minsz),s2); 
    } 
  } 
  else 
    return s1>s2; 
} 

int main()
{
    //freopen("my.in","r",stdin);
    //freopen("my.out","w",stdout);

    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    cin>>num[i];

    sort(num+1,num+n+1,cmp);

    for(int i=1;i<=n;i++)
    cout<<num[i];

    return 0;
}

<代碼2>

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
#include<set>
#include<cstdlib>
#define maxn 25
using namespace std;
int n;
struct data
{
    char s[100];
}A[maxn];

bool cmp(data a,data b)
{
    char t1[100],t2[100];

    strcpy(t1,a.s);
    strcat(t1,b.s);

    strcpy(t2,b.s);
    strcat(t2,a.s);

    if(strcmp(t1,t2)>0)return 1;
    return 0;
}


int main()
{
    //freopen("my.in","r",stdin);
    //freopen("my.out","w",stdout);

    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%s",A[i].s);

    sort(A+1,A+n+1,cmp);

    for(int i=1;i<=n;i++)
    printf("%s",A[i].s);

    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章