CF277Div2ProC

这种题我非常不擅长,对于给定的m,s找到最大和最小的数,使得位数分别为m且各位数之和为s,如果不存在返回-1

这道题目其实如果没写好可能会写残掉,就比如我。夫神思路非常清楚,而且1A,关键是他能够代码重用。

http://codeforces.com/contest/489/problem/C
我已开始自己写就是贪心的去试,最大的就高位大,最小的从低位开始选大的,同时保证第一位至少为1。

最大的代码倒还好,

string MaxAns(int m, int s)
{
    string maxans(m, '0');
    int remain=s;
    for(int i=0;i<m;i++)
    {
        maxans[i]=min(remain, 9)+'0';
        remain-=(maxans[i]-'0');
    }
    if(remain) return "-1";
    return maxans;
}

最小的话我一直出错,已经各种corner case,例如s=0,等等。后来夫神说min和max很相像,因此可以重用这段,但是reverse之后可能高位为0,
因此再s-1去调用,高位再改为1,就可以了。

最主要是我即使按照这个思路还是一直wa,后来总结s=0的情况最好是单独拿出来处理,里面可能因为s=0就出错,于是clean的代码终于被我搞好了T T

string MaxAns(int m, int s)
{
    string maxans(m, '0');
    int remain=s;
    for(int i=0;i<m;i++)
    {
        maxans[i]=min(remain, 9)+'0';
        remain-=(maxans[i]-'0');
    }
    if(remain) return "-1";
    return maxans;
}
string MinAns(int m, int s)
{
    string minans=MaxAns(m, s);
    if(minans=="-1") return "-1";
    reverse(minans.begin(), minans.end());
    if(minans[0]!='0') return minans;
    minans=MaxAns(m, s-1);
    if(minans=="-1") return "-1";
    reverse(minans.begin(), minans.end());
    minans[0]='1';
    return minans;
}

int main()
{
/*
#ifndef ONLINE_JUDGE
    freopen ("in.txt" , "r" , stdin);
    freopen ("out.txt" , "w" , stdout);
#endif
*/
    int m ,s;

    while(cin>>m>>s)
    {
        if(!s && m>=2) cout<<"-1 -1"<<endl;
        else if(!s && m==1) cout<<"0 0"<<endl;
        else
            cout<<MinAns(m, s)<<" "<<MaxAns(m, s)<<endl;
    }
    return 0;
}

Posted by richard爱闹 - 3月 15 2015
如需转载,请注明: 本文来自 Richard