CF758D---Ability To Convert(模拟+贪心思想(仅仅是思想))

【题目来源】http://codeforces.com/problemset/problem/758/D
【题意】
根据16进制的11311可以转化为十进制的475,过程是:
475 = 1·162 + 13·161 + 11·160
然后给出一个进制,再给出一个数,问,此进制下的这个数按这种方法转化为十进制的值是多少?
【思路】
看上面的那个式子,每次选的数字(例如:11,13,1)都是小于进制(例如16)的,也就是说,要尽可能的使得得到的最终结果最小,那么就要用到贪心的思想,也就是每次取到不能取为止。
然后,就是这道题的特色了:“0”的处理
比如1000 10001,那么这个结果是多少呢?是100000001。
而转换成代码呢就应该是这样的描述:
先判断1是否可取,可取,(倒着来),判断0是否可取,可取,再取0,直到取到左边第一个0,会发现,所取的这几个数字的长度(此时对应的是10000)已经大于进制,那么一定不可能,所以,丢掉后面所有不为0的数字,能丢几位丢几位,只剩下三个0,长度为3,此时再取1,但是发现此时的数字拼凑起来刚好是1000,等于进制,所以,只好去掉一个0,得到100,然后写出式子:1*1+0*1000+100*1000*1000;
【代码】

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int mod=1e9+7;
typedef long long LL;
const int INF=1e9;
char string_con[70];
int n;
int main()
{
    while(~scanf("%d",&n))
    {
        getchar();
        scanf("%s",string_con);
        int len_con=strlen(string_con);
        int i=len_con-1;
        LL mid=1,ans=0,tmp=1,when=0;
        int flag=0;
        while(i>=0)
        {
            if(!flag) mid=1;//可以看成是记录当前数字位数,每次乘10
            flag=0;
            int j=i;
            when=0;//当前结果
            while(j>=0)
            {
                if(mid>=n)
                {

                    flag=1;
                    break;
                }
                if(when+(string_con[j]-'0')*mid>=n)
                {
                    if((mid/10)>when&&i!=j)//i!=j是为了让000能加上一个1再进行处理
                        flag=1;
                    break;
                }
                when+=(string_con[j]-'0')*mid;
                mid*=10;
                j--;
            }
            ans+=when*tmp;
            if(flag)
            {
                if(when==0)//是为了刚才那个样例的特殊情况000(此时还没有1)
                {
                     mid/=10;//去掉一个0,然后下一步去加上数字1
                }
                else
                {
                    while(when)//能丢几个丢几个,反正小于进制
                    {
                        when/=10;
                        mid/=10;
                    }
                }
            }
            tmp*=n;//进制每次乘本身
            i=j;
        }
        printf("%lld\n",ans);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值