新生赛G题

这道题wa了四下。wa的最多很多数据都过了,但是就是不能a。
下场,大佬一提醒,发现了错误然后A了,也是很心累了。过了就进前五了。
以下为题目
LLLYYY的数字思维
Description LLLYYY很喜欢写暴力模拟贪心思维。某一天在机房,他突然抛给了队友ppq一个问题。问题如下:
有一个函数f ():
int f(int x)
{
int tmp = 0;
while(x != 0)
{tmp += x % 10;
x /= 10;}
return tmp;
}
接着LLLYYY给定一个整数 c,要求在c范围内找两个整数a和b,使得a + b = c,且f(a) + f(b)的值最大。 Input 采用多组输入方式。每行输入一个整数 c (1 <= c <= 1e12). Output 对于每一个 c,找到一组 a,b ,使 f(a) + f(b)最大 且 a + b = c,输出这个f(a) + f(b)(0 <= a,b <= c).
Sample Input 1
35
10000000000
Sample Output
1
17
Hint 在第一个样例中,可以选择 a = 17,b = 18,这样得到的f(a) + f(b)值最大为 17。在第二个样例中, 可以选择 a = 5000000001,b = 4999999999.这样得到的f(a) + f(b)值最大为 91。
自己A了的代码
基本思路就是先将数平分构造九最多的数c,然后用总数减掉c得到a。
这个题被误导了一下,Hint说将数字平分一下,其实不用,直接构造即可。唉~(比赛的时候,按照Hint写,奇数(a为n/2,c为n/2+1)偶数(a为n/2-1,c为n/2+1)结果在18错了(其实在所有9+9,19+19,都会错理由太简单了))

#include<iostream>
using namespace std;
typedef long long ll;
ll f(ll a)
{
    ll sum=0;
    while(a/10!=0)
    {
        sum+=a%10;
        a/=10;
    }
    sum+=a;
    return sum;
}
int main()
{
    ll n;
    while(cin>>n)
    {
        ll a,c1,c;
        c1=n/2;//平分数
        c=c1;ll ws=0;//求位数
        while(c1/10!=0)
        {
            c1/=10;
            ws++;
        }
        //构造a,p比如500p求出来为100q为99
        ll p=1,q=9;
        for(ll i=0;i<ws;i++)
        {p*=10;q+=9*p;}
        a=n-c/p*p-q/10;//c/p*p将c的个十位清空q/10为c的个十位
        cout<<c/p+ws*9+f(a)<<endl;
    }
}

接下来是标准答案
标准答案大体思路是相同的只不过选择模拟挑选9最多的数(我直接构造)
我一开始的思路是模拟,但是被Hint坑了,从中间开始找9最多,结果超时了,然后想到直接构造,然而最开始还是平分c=n/2+1就凉了。

#include<bits/stdc++.h>
#define ll long long
using namespace std;


int main() {
    ll n, a, b;
    while(cin >> n) {
        ll m = n, k = 9;
        while(m >= k) {
            k = k * 10 + 9;
        }
        k /= 10;
        a = k;
        b = n - k;
        ll sum = 0;
        while(a) {
            sum += a % 10;
            a /= 10;
        }
        while(b) {
            sum += b % 10;
            b /= 10;
        }
        cout << sum << endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43331783/article/details/85237139