\(len\le 1000000\)
像这种数据范围基本就是 \(O(n)\) 扫了
我们倒着扫,记 \(s_{i}\) 为当前位的数字,\(s_{i-1}\) 为前一位
如果 \(s_i\) 为 10(在后面的操作中会出现的),那么就执行进位 \(s_i=0,s_{i-1} =s_{i-1}+1\)
如果 \(s_i<5\),那么很明显用 \(s_i\) 张是最优的
如果 \(s_i>5\),那么就用一张大的去换 \(10-s_i\) 张小的,因为 \(s_i>5\),即使是最坏的情况 \(s_{i-1}<5\):进一位会让前一位多消耗一张,但 $10-s_i+1+1\le s_i $ 明显成立,所以一定不会更劣,反而有可能更优
如果 \(s_i=5\),就要分类讨论了
如果 \(s_{i-1}\ge5\),那么此时进一位会让前一位少使用一张,明显更优,于是就用一张大的去换 \(10-5=5\) 张小的
如果 \(s_{i-1}<5\),那么此时进一位会让前一位多使用一张,明显更劣,于是直接用 5 张就行了
注意要判断 \(s_0\) 最后是否有被进位
// This code wrote by chtholly_micromaker(MicroMaker)
#include <bits/stdc++.h>
#define reg register
using namespace std;
const int MaxN=1000050;
template <class t> inline void read(t &s)
{
s=0;
reg int f=1;
reg char c=getchar();
while(!isdigit(c))
{
if(c=='-')
f=-1;
c=getchar();
}
while(isdigit(c))
s=(s<<3)+(s<<1)+(c^48),c=getchar();
s*=f;
return;
}
char s[MaxN];
signed main(void)
{
scanf("%s",s+1);
reg int n=strlen(s+1);
s[0]=0;
reg int ans=0;
for(int i=1;i<=n;++i)
s[i]-='0';
for(int i=n;i>=1;--i)
{
if(s[i]==10)
{
s[i]=0;
++s[i-1];
}
if(s[i]==5)
{
if(s[i-1]>=5)
{
++s[i-1];
ans+=5;
}
else
{
ans+=5;
}
}
else if(s[i]<5)
{
ans+=s[i];
}
else if(s[i]>5)
{
ans+=10-s[i];
++s[i-1];
}
}
ans+=s[0];
cout<<ans<<endl;
return 0;
}