Good Ticket(深搜)

最近小A得到了一串号码——一个包含了 n 个数字 a_1 a_2 … a_n的数列。小A认为一个数列是超级号码,如果它能被分为两个或更多的有相同值的部分。例如,号码350178 是超级号码因为它可以被分为三个部分350, 17 和 8: 3+5+0=1+7=8。每一个数字只能属于一个部分 。

帮小A看看他的号码是不是超级号码。

Input
第一行包含一个整数 n (2 <= n <= 100) — 号码的数字个数

第二行包含 n 个数字 a_1 a_2 … a_n (0 <= a_i <= 9) — 小A的号码. 数字间没有空格。

Output
如果是超级号码则输出 “YES”, 否则输出 “NO” (不带引号)。

Examples
Input
5
73452
Output
YES
Input
4
1248
Output
NO
Note
第一个样例分为了三部分 7, 34 和 52: 7=3+4=5+2。

第二个样例不是超级号码。
题解
这个题是昨天没写出来的,然后今天重新理了一下,发现是昨天没有处理好数字里面有0的问题,其实数字串里面的0完全可以去掉,对结果没有任何影响,而且还能简化代码的难度。
关于这题的输入
还有就是很多人喜欢用字符串存这一串数字,最后转化成整型数组,其实可以直接用整型数组输入,不需要多一步转换的操作。
其实scanf的格式字符串里,%nd代表输入一个 长度<=n的整型 变量,所以这题的输入我们用 %1d 就行了。
AC代码:

#include <bits/stdc++.h>
using namespace std;
bool dfs(int num, int *a, int size)
{
    if (size == 0)
        return true;
    int sum = 0;
    for (int i = 0; i < size; i++)
    {
        sum += a[i];
        if (sum > num)
            return false;
        else if (sum == num)
            return dfs(num, a + i + 1, size - i - 1);
    }
    return false;
}
bool solove(int *a, int size)
{
    if (size == 0) //如果输入全部都是0
        return true;
    int num = 0;
    for (int i = 0; i < size - 1; i++) //保证最低拆成两部分,最后一位不能累加
    {
        num += a[i];                           //计算前n项和num,然后以num为相同的数字,向后面搜索。
        if (dfs(num, a + i + 1, size - i - 1)) //如果可以拆成若干个num,说明是超级数字
            return true;
    }
    return false;
}
int main(void)
{
    int n;
    int a[120];
    scanf("%d", &n);
    int size = 0;
    for (int i = 0, x; i < n; i++)//输入可以不用字符串
    {
        scanf("%1d", &x); //%1d表示一次只读一位
        if (x != 0)       //如果输入有0,可以直接去掉,去掉不会影响超级数字的结果,而且还能简化代码的逻辑
            a[size++] = x;
    }
    if (solove(a, size))
        puts("YES");
    else
        puts("NO");
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值