B2 - E - Efficient Exchange(思维+ 贪心)

这题是看了这位大佬的代码:原文网址

题目:

 题意:虽然我不懂,但是“贪心”我感觉还是挺符合这题的意思的,就是说你只有1块,10块,100块,……面额的硬币,输入一个物品的价格,你给服务员钱,多给了他会找给你,服务员拥有的面额同也是1,10,100,……。问这次交易最少涉及多少硬币数(你给服务员的+服务员找给你的)?还有给举的实际例子,就是讲的题意。

分析过程:先看数据范围,吓死了。10^1000,透漏出两个信息:①不能像题干举例那样列出所有的可能然后对比,必须一步到位;②输入可能会很长,长到无法按数来计算,只能是一位一位地拆开来研究,但是又得找到每一位(相邻位)之间的关系,最终确定硬币数。在我自己试了好多例子之后+看了那位大佬代码中关键的一句(“对于小于5的位肯定是直接付比较优,大于5的话肯定是付10这种更优,等于5的时候……”)发现,确实和大佬说的一样-_-(下次争取自己发现规律!!!!)然后是付10的话是得进一位,比如368,8>5,付10,满10进1(这10不付,进1到下一位) 找 2 =2枚,6+1 = 7,7 > 5,付10,满10进1(这10不付,进1到下一位) 找 3 =3枚,3+1 = 4,4 < 5,付4枚。4+3+2=9枚

……描述起来有点困难,总之就是大胆猜测,小心求证。多举一些例子验证一下自己找的规律是不是很有普遍性,然后考虑一下代码实现的可能性。符合这两点就写写试试呗,我感觉做题就是这么个过程吧!

自己写的码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;

int main() {
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
    char s[1005];
    int st[1005];
    int i;
    cin >> s;
    for(i = 0; i < (int)strlen(s); i++)
        st[i] = s[i] - '0';//把每一位的字符变成相应的数字
    int sum = 0;
    for(i = (int)strlen(s) - 1; i > 0; i--) {
        if(st[i] < 5)
            sum += st[i];
        else if(st[i] == 5) {
            if((st[i - 1] + 1) > 5) {
                sum += 5;
                st[i - 1]++;
            } else
                sum += 5;
        } else if(st[i] < 10) {
            sum += 10 - st[i];
            st[i - 1]++;
        } else
            st[i - 1]++;
//上面就是对每一位的大小进行各种情况的讨论,0≤x≤5,x=5,5<x<10,x=10(因为涉及到进位,所以有这种情况)
    }
    if(st[i] > 5)//第一位需要单独进行判断,规律和后面的不完全一样
        sum += 11 - st[i];
    else
        sum += st[i];
    cout << sum << endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值