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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章