Codeforces Test Round 10 C 水搜索

来源:互联网 发布:南京哪里体检好 知乎 编辑:程序博客网 时间:2024/05/29 10:01

只用含有 1 的式子构成数字,要求含有 1 的个数最少

121 = 111 + 11 - 1

一开始用的贪心的方法,但是总觉得战战兢兢的,很明显,对于一个数字,要么用比他稍大一号的 111 ,要么用比他稍小一号的 111 ,但是到底用哪个是不确定的。

这个地方就要用到搜索了。显然,缩小过程中 n 的正负对结果无影响。 而且每一步都必须缩小 n. 每一步都差不多缩小一个数量级,妥。

#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <queue>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <cctype>#include <string>#include <cstring>#include <cstdio>#include <cmath>#include <cstdlib>#include <ctime>using namespace std;#define PII pair<int,int>#define MS(x,d) memset(x,d,sizeof(x))#define ALL(x) x.begin(),x.end()#define ll long longll num[20];ll ans;void dfs(ll n, ll ta){if(ta>=ans)return ;if(n==0){ans=min(ta,ans);return ;}    int i=lower_bound(num,num+15,n)-num;    if(num[i]-n<n)    dfs(num[i]-n,ta+i+1);    if(i!=0&&n%num[i-1]<n)    dfs(n%num[i-1],ta+(i)*(n/num[i-1]));    return ;}int main(){    ll n;    cin>>n;    {    num[0]=1;    for(int i=1;i<=15;i++)        num[i]=num[i-1]*10+1;    ans=0x3f3f3f3f;dfs(n,0);cout<<ans<<endl;}    return 0;}
思路差不多,但是显然更好想的一发代码。直接使用组合来求解。
<pre name="code" class="cpp">#include <cstdio>#include <iostream>using namespace std;long long n;long long p[16];long long  Count(long long n, int i) {    long long ret = (i+1LL)*(n/p[i]);    n %= p[i];    if (n == 0) return ret;    return ret + min(Count(n, i-1), i+1 + Count(p[i]-n, i-1));}int main() {    // freopen("I.txt", "r", stdin);    p[0] = 1;    for (int i = 0; i < 16; i++)        p[i] = p[i-1]*10 + 1;    cin >> n;    cout << Count(n, 15);    return 0;}




0 0
原创粉丝点击