题目链接:http://codeforces.com/contest/758/problem/D
cf392 div2的D题
题意大概就是给一个n进制,然后再给一串数字,把这串数字从右到左放在这些进制位上,每个位置上放的数字必须小于n,而且如果是0的话只能放一个0。最后问怎么放使得这个n进制的数字最小。
贪心一下,尽量先填满低位的数字,但是有很麻烦的判断地方就是假设某个进制放了几个0之后再放一个非0的数字就会超过n了,那么这个进制上就只能放一个0,
还有每个位置上的数字是不能带有前导0的,还有就是假设一个位置上放的0的个数已经超过了n的位数之后,就不用再放了,直接在这位上放一个0即可,否则有可能会爆long long。
总之是贪心加上好多挺麻烦的判断,我看好多dalao的代码是用dp过的,不太懂……
#include <bits/stdc++.h>
using namespace std;
long long p[200];
long long POW (long long a , int b)
{
long long res = 1;
while(b--)
res *= a;
return res;
}
int de(long long x)
{
int res = 0;
while(x)
{ x /= 10 ; res ++ ;}
return res ;
}
int main() {
long long n ;
string k;
cin>>n>>k;
int dem = de(n);
long long ans = 0;
int len = k.length();
int p = 0;
long long num = 0;
int j = 0;
int judge = 0;
for(int i = len - 1 ; i >= 0 ; )
{
long long tmp =k[i] - '0';
//cout<<num + num + tmp *POW(10 , j)<<endl ;
if(judge >= dem)
{
if(j>judge)
{
i += judge ;
judge = 0 ;
j = 0;
}
else
{
i += (judge - 1 );
judge = 0;
j = 0;
}
long long temp = num * POW( n , p) ;
ans += temp;
num = 0;
p ++ ;
// cout<<temp<<endl;
continue ;
}
if(num + tmp *POW(10 , j) < n)
{
num += tmp * POW(10 , j) ;
if(tmp == 0)judge ++ ;
else judge = 0;
// cout<<judge <<endl;
if(i == 0)
{
ans += num * POW( n , p) ;
// cout<<num<<endl;
break ;
}
++ j;
i -- ;
}
else
{
// cout<<judge<<" "<<j<<endl;
if( judge >= 1 && j > judge ) i += (judge ) , judge = 0;
else if(judge >= 2) i+= (judge - 1) , judge = 0 ;
j = 0;
ans += num * POW(n , p );
// cout<<num<<endl;
p++;
num = 0;
}
}
cout<<ans<<endl;
}