Recently Vasya found a golden ticket — a sequence which consists of nn digits a1a2…ana1a2…an. Vasya considers a ticket to be lucky if it can be divided into two or more non-intersecting segments with equal sums. For example, ticket 350178350178 is lucky since it can be divided into three segments 350350, 1717 and 88: 3+5+0=1+7=83+5+0=1+7=8. Note that each digit of sequence should belong to exactly one segment.
Help Vasya! Tell him if the golden ticket he found is lucky or not.
The first line contains one integer nn (2≤n≤1002≤n≤100) — the number of digits in the ticket.
The second line contains nn digits a1a2…ana1a2…an (0≤ai≤90≤ai≤9) — the golden ticket. Digits are printed without spaces.
If the golden ticket is lucky then print "YES", otherwise print "NO" (both case insensitive).
5
73452
YES
4
1248
NO
In the first example the ticket can be divided into 77, 3434 and 5252: 7=3+4=5+27=3+4=5+2.
In the second example it is impossible to divide ticket into segments with equal sum.
【题意】:
题意的大概意思是是不是存在两组以上的序列使得他们相等,比如 773434 可以等价于 7 = 7 = 3 + 4 = 3 + 4
【思路】:
我的思路是先求一次前缀和,然后我们要判断的是存不存在大于2组的序列,那么前缀和sum[n] = x * n;x是满足的序列
那么我们只要假设x,然后翻倍向上求就可以了,翻倍查询是不是存在,x * 1, x * 2, x * 3 -----x * n这样的前缀和,因为
这个的总和很少,所以我们可以开一个足够大的标记数组来标记sum[i],,,,,,sum[n]的数值,这样的话,查询的复杂度就是O(1)了
我们只要枚举sum[i] ----sum[m],如果sum[m] > sum[n] / 2的话就不用判断了,因为肯定不存在答案,大概复杂度是O(n * log n sum[i])
因为数据量不大,所以可以通过
全都是0的情况需要特判
附上代码:
#include <cstdio> #include <cstring> #include <iostream> using namespace std; int flag[2000]; int math[2000]; int sum[2000]; char str[1005]; int main() { int n; while(~scanf("%d",&n)) { memset(flag, 0, sizeof(flag)); memset(math, 0, sizeof(math)); memset(sum, 0, sizeof(sum)); memset(str, 0, sizeof(str)); scanf("%s",str); for(int i = 0; i < n; i ++) { math[i] = str[i] - '0'; } sum[0] = math[0]; flag[sum[0]] = 1; for(int i = 1; i < n; i ++) { sum[i] = sum[i - 1] + math[i]; flag[sum[i]] ++; } if(flag[0] >= 2 && sum[n - 1] == 0) { printf("YES "); continue; } else { int nums = sum[n - 1] / 2 + 1; int cs = 0; for(int i = 0; i < n; i ++) { if(sum[i] == 0) continue; if(cs) break; if(sum[i] > nums) break; else { int summ = 0; int fff = 1; int ff = 0; while(summ < sum[n - 1]) { //printf("... "); summ = summ + sum[i]; ff ++; if(flag[summ] >= 1 && summ == sum[n - 1] && ff >= 2) { fff = 0; break; } if(!flag[summ]) { fff = 1; break; } } //printf("%d %d ",ff,fff); if(!fff) { printf("YES "); cs = 1; break; } } } if(!cs) printf("NO "); } } return 0; }