B.A+B

题目链接:https://ac.nowcoder.com/acm/contest/11176/B

题意:

若一个数字字符串可以分成连续的三部分,将每部分看成数字,可以使前两部分代表的数字之和等于第三部分代表的数字称其为满足条件的字符串(即字符串 s=A+B+C,(int)A+(int)B=(int)C)(分成的数前面不能有前导 0)。现给定 k,n,输出 n 个有 k 种分法的满足条件的字符串。(\(0\le k \le 2,1\le n \le 100\),每个字符串长度不超过 30)

思路:

对于 k=0、1、2 三种情况,每种情况用一个可以输出大于 100 种结果的循环输出,到 n 种就停止。

  1. 对于 k=0 的情况,输出 1、11、111、2、22...这样形如 \(iiiii...\) 的字符串。
  2. 对于 k=1 的情况,输出"十十乘法表",即 111,122,133,...9981,1010100 这样的字符串。
  3. 对于 k=2 的情况,枚举前两个数的总长度 3~15,构造一个此长度的字符串,保证所有数字均相同(只包含 1~9 其中的一个数字),再将字符串分成任意长度不等的两部分形成两个数相加作为第三个数,三个数连接成一个字符串输出。

代码:

#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
ll num(ll i, ll k) //返回由k个数字i组成的数
{
    ll ans = 0;
    while (k)
    {
        ans += i;
        i *= 10;
        k--;
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, k;
    cin >> k >> n;
    int cnt = 0;
    if (k == 0)
    {
        for (int i = 1; i <= 9; i++)
        {
            for (int j = 1; j <= 30; j++)
            {
                for (int l = 1; l <= j; l++)
                    cout << i;
                cout << endl;
                cnt++;
                if (cnt == n)
                    return 0;
            }
        }
    }
    else if (k == 1)
    {
        for (int i = 10; i <= 100; i += 10)
        {
            for (int j = 10; j <= 100; j += 10)
            {
                cout << i << j << i + j << endl;
                cnt++;
                if (cnt == n)
                    return 0;
            }
        }
    }
    else
    {
        for (ll i = 1; i <= 9; i++)
        {
            for (ll j = 3; j <= 15; j++)
            {
                for (ll l = 1; l < j / 2; l++)
                {
                    ll t1 = num(i, l), t2 = num(i, j - l);
                    cout << t1 << t2 << t1 + t2 << endl;
                    cnt++;
                    if (cnt == n)
                        return 0;
                }
            }
        }
    }
}

总结:

posted @ 2021-07-10 17:17  Wajor  阅读(40)  评论(0)    收藏  举报