貪心算法 刪數問題

目錄

 

題目描述

輸入格式

輸出格式

輸入輸出樣例

分析:


題目描述

鍵盤輸入一個高精度的正整數NN(不超過250250位) ,去掉其中任意kk個數字後剩下的數字按原左右次序將組成一個新的正整數。編程對給定的NN和kk,尋找一種方案使得剩下的數字組成的新數最小。

輸入格式

nn (高精度的正整數)

kk(需要刪除的數字個數)

輸出格式

最後剩下的最小數。

輸入輸出樣例

輸入 #1複製

175438 
4

輸出 #1複製

13

 



分析:

- 首先:要讓剩餘的數最小,由於刪的個數是確定的,即剩餘的個數是確定的。當高位數字越小時,得到剩餘的數字就越小。如此便得到此題的關鍵。

- 若要從長度爲len的數中,刪掉m個數字。首先如何確定要保留的最高位數字?

如果從34125中刪掉2個數,顯然最高位是1

如果從31245中刪掉2個數,顯然最高位仍然是1

如果從34215中刪掉2個數,最高位最小隻能是2

 

由此得到結論:第一位數字要從前m+1個數中選擇一個最小的,前面的刪掉。

 

- 同樣的,第二位數字的選擇和第一位是一樣的道理。如果此時m已經用完,直接把後面的數拼接到結果數組中即可。否則仍按照上述規則尋找。

 

- 如果僅想到上面這些,並不能AC。原因是0的存在。。。。。。。

舉個栗子:

從50074897中刪除2個。答案是4897.

如果仍然按上述規則寫,答案卻是004897,此時,只需要考慮保存答案數組時,特判一下是否是0即可。

 

- 最後,把上面的全做完了,但。。。。。仍然不能AC。。。。。。。TMD!!!

再舉個梨子,從10000中刪除兩個數。答案是0。按照上述規則來寫,最後沒有輸出,因此,特判一下結果數組的長度,如果最後結果數組的長度是0,直接輸出0.

 

代碼如下:

#include <bits/stdc++.h>
using namespace std;

const int MAX = 255;
char str[MAX],res[MAX];
int N;

int main() {
    gets(str);
    scanf("%d",&N);
    int x = 0;
    while (str[x]=='0') x++;        //清空一下給出數字的前導0
    if(x) strcpy(str,str+x);
    int countRes=0,cut=0;
    for(int i=0; i+N+1 < strlen(str); i++) {
        if(N==0) {
            strcpy(res+countRes,str+i);    //已經刪完,把後面的數拼接過來即可
            break;
        }
        int bk=i;
        for (int j = 0; j < N; ++j) {
            if(str[i+1+j]<str[bk]) {
                bk=j+1+i;
            }
        }
        N-=bk-i;                        //此次需要刪除多少個,刷新一下N
        if(str[bk]!='0'){
            res[countRes++]=str[bk];      //特判,如果不是0才能添加到結果數組中
        }
        i=bk;                            //恢復i的索引。
    }
    if(countRes) puts(res);
    else puts("0");
}

 

 

 

 

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