最近小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");
}