Codeforces Round #392(div 2) 758D (贪心)

orz 最近被水题卡+FST,各种掉rating

题目大意

一个数s它是n进制的,但是每一位不是用'A','B'....表示的,而是用10,11等等表示的,将它还原成十进制

这种表示方法显然会产生多解,然后求所有的解中最小的那个

 

这题一想就是贪心,但是一开始算法写渣了,改变思路以后才A的

简单来说就是从右边开始,把尽量多的数压到一位里面,这样会使数更小

压的思路可以这么考虑

每次新加进来一个数,如果加进来以后,已经大于原来的那个数,那么就找截取一段可行的最大数

这样考虑的目的是处理前导0带来的影响

0也有可能是单独的一位,也有可能与其他数压到同一位里

想清楚这个以后就不难写了

 

#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long ll;
string str, n;
ll last, w;
bool compare(int x, int y)
{
    if(y-x > n.length()) return true;
    if(y-x < n.length()) return false;
    for(int i = x; i < y; i++)
    {
        if(str[i] == n[i-x]) continue;
        if(str[i] > n[i-x]) return true;
        else return false;
    }
    return true;
}
ll cal(string str, int x, int y)
{
    ll ans = 0;
    for(int i = x; i < y; i++)
        ans = ans*10 + str[i] - '0';
    return ans;
}
int main()
{
    cin>>n;
    cin>>str;
    ll ans = 0, k = 1;
    last = str.length();
    for(int i = str.length()-1; i >= 0; i--)
    {
        while(compare(i, last))
        {
            int j;
            for(j = i; j < last; j++)
            {
                if(str[j] == '0') continue;
                if(compare(j, last)) continue;
                j++; break;
            }
            j--;
            ans += cal(str, j, last)*k;
            last = j;
            k *= cal(n, 0, n.length());
        }
    }
    if(last != 0) ans += cal(str, 0, last)*k;
    cout<<ans<<endl;
}

 

posted @ 2017-01-20 13:24  Saurus  阅读(209)  评论(0编辑  收藏  举报