这题是看了这位大佬的代码:原文网址
题目:
题意:虽然我不懂,但是“贪心”我感觉还是挺符合这题的意思的,就是说你只有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;
}