EOJ 3290 找數(III) (模擬+簡單數字串)

題目

http://acm.ecnu.edu.cn/problem/3290/

題意:“非上升數”表示一個整數的高位數碼不會小於低位數碼。如54332111, 111等。給定一個整數n,找出不小於n的最小“非上升數”。

解題思路

最自然的想法是,通過掃描s[i] < s[i+1]找到上升點,然後對上升點前的s[i-1]+1,後面全部填0。但是要考慮到s[i-1]+1後可能會破壞前面的非上升序列,因此還要將前面的元素考慮進來。

採取的辦法是,在掃描上升點的同時,維護經過的最小數字及位置,找到上升點後,判斷s[i-1]+1和該最小數字的大小,如果s[i-1]+1更小,那就在後面填0即可,否則要對最小數字+1,並在其後全填0。(實質是讓填0前的那個數字保持最小)

例子:7400920的上升點在第二個0和9之間,如果變成7101000不滿足“非上升”,但是變成7410000則滿足。

AC代碼

#include <iostream>

using namespace std;

int main()
{
    int kase;
    cin >> kase;
    string s;
    for(int t = 0; t < kase; ++t)
    {
        cin >> s;
        int min_num = 10, min_pos = 0; //最小數字及所在小標
        for (int i = 0; i < s.size()-1; ++i)
        {
            if (s[i] < s[i+1]) //出現上升
            {
                int tmp = s[i] - '0' + 1, pos = (tmp>min_num)?min_pos:i; //pos爲更新的位置
                //要更新的數字加1,後面全填0
                s[pos]++; 
                for(int j = pos + 1; j < s.size(); ++j)
                    s[j] = '0';
                break;
            }
            else if (s[i]-'0' < min_num) //維護經過的最小數字
            {
                min_num = s[i] - '0';
                min_pos = i;
            }
        }
        cout << "case #" << t << ':' << endl;
        cout << s << endl;
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章