c語言解決the next permutation 問題

問題描述就直接用現成的了,主要說下我的設計思路和算法

Description

 
For this problem, you will write a program that takes a (possibly long) string of decimal digits, and
outputs the permutation of those decimal digits that has the next larger value (as a decimal number)
than the input number.  For example:
 
123 -> 132
279134399742 -> 279134423799
 
It is possible that no permutation of the input digits has a larger value.  For example, 987.

Input

 
The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets that
follow.  Each data set is a single line that contains the data set number, followed by a space, followed
by up to 80 decimal digits which is the input value.
 

Output

 
For each data set there is one line of output.  If there is no larger permutation of the input digits, the
output should be the data set number followed by a single space, followed by the string BIGGEST.  If
there is a solution, the output should be the data set number, a single space and the next larger
permutation of the input digits.
 
 

Sample Input

3
1 123
2 279134399742
3 987

Sample Output

1 132
2 279134423799 
3 BIGGEST 

以上的問題的描述,這是一道ACM的競賽題

開始的思路是用int來處理,但是發現長度不夠,用字符串來處理了

 

設計思路:

從最後出發,看是否是非遞減序列,一直到非遞減的第一個字符,記爲change,把前非遞減序列保存在一個數組gg1[]中,如2345667543321 中 我們從1出發一直到7都是非遞減的,gg1[]中爲gg1[]=“1233457”,change=6;同時把剩餘的序列保存在gg2[]中

gg2[]=“23456”(正序),在gg1[]中搜索找到比change大第一個數 在gg1[]="1233457"中這個數爲7,change和這個數交換,現在gg1[]=1233456 change=7;把change插到gg2中的最後位置gg2=“234567” gg3=gg2+gg1;gg3就是最小的大於原數的數

一下是幾個例子:gg爲原數組,其他定義不變:

1:gg=123345698765

gg1=56789

change = 6

交換後:

change與7交換:

gg1=56689

 

gg2=123345

gg2=gg2+change = 1233457

gg3 = gg2+gg1=123345756689

2:

gg = 45678

gg1=8

change = 7

gg1交換後

gg1=7

change=8

gg2=4568

gg=gg2+gg1=45687

3:

gg=987654321

這時gg1=123456789而且gg1,gg2長度相等,說明gg爲最大數:輸出:BIGGEST

 

代碼如下:

(點點取巧,沒把gg1和gg2連接起來,直接在輸出的地方控制了一下):

 

 

#include <iostream>
#include <string>
#include<string.h>
using namespace std;
int main()
{   int i;
string name[1000];//用於保存輸入的字符串組,每組都單獨處理
 int a[1000];//用於保存組數的序號
 char gg[1000]; //文章中的gg
 char gg1[1000];//文章中的gg1

 string result[1000];
   
     int t = 0;
  cin >> t;
    for (i = 0; i < t; ++i)
    {
  cin >> a[i];
        cin >> name[i];
  
    }
 for(i = 0;i<t;++i){
  strcpy(gg,name[i].c_str());
  int flag = 1;//標記找到了change,這裏的change用hh代替了 ,因爲我程序和文章不是同一時間寫的
  int flag1 =1;//表示輸入爲最大
  char hh;
  char wo;
  int len = strlen(gg);
  if(len<=1) flag1 =0;//只有一位時默認爲最大
  gg1[0] = gg[len-1];
   int temp = len-2;
   int fus = 0;
  while(flag&&(temp+1)){
   if(gg1[fus]<=gg[temp]){
      gg1[fus+1]=gg[temp];
      temp--;
      fus++;
      hh = gg[temp];
   }else{
      hh = gg[temp];
      flag = 0;
   }
   if(temp+1 ==0){
    flag1 = 0; //當gg和gg1長度相等時,說明輸入的序列是最大的  
   }
   gg1[fus+1] = '\0';

  }
  if(flag1){//輸入不是最大時按上文中處理
   for(int j= 0;j<=fus;j++){
   if(hh<=gg1[fus]){
    wo = hh;
    hh = gg1[fus];
    gg1[fus]= wo;
   }
  }
  gg[temp] =hh;//這
  gg[temp+1]='\0';// 這兩行代碼相當於gg2保存到了gg中
  printf("%d %s%s\n",a[i],gg,gg1);//gg gg1一起輸入,其實輸出的是文中的gg3
  
  }else{
   printf("%d BIGGEST\n",a[i]);//最大是直接輸出BIGGEST;
  }
  
 
 }
    return 0;
}

 

驗證

輸入:

5
1 3243256436547858954324324
2 4
3 45
4 76543321
5 3456436576547568687987879870870543523421354375687687685

輸出:

1 3243256436547858954324342
2 BIGGEST
3 54
4 BIGGEST
5 3456436576547568687987879870870543523421354375687687856

輸入:

3
1 0998766123
2 000000000
3 11

輸出:

1 0998766132
2 BIGGEST
3 BIGGEST

 

 

程序初步驗證沒有問題,如有讀者發現漏洞,請指正!

 


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