5865: 桃子的幸运彩票
http://www.tzcoder.cn/acmhome/problemdetail.do?&method=showdetail&id=5865
时间限制(普通/Java):1000MS/3000MS 内存限制:65536KByte
描述
最近桃子爱上了博彩,一天他买了一张彩票,上面印着带有n个数字的序列a1a2a3...an。
如果一张彩票是幸运的,当且仅当其满足如下全部条件:
1. 序列能被恰好分成不相交的至少2段;
2. 每一段区间[l,r]的和都是相同的。
请你帮助桃子判断他手上的彩票是不是幸运的。
例如123426是幸运的,它可以分为3段,123、42和6,1+2+3=4+2=6。
不相交就是序列的每个数字恰好属于一个段。
输入
第一行一个整数T(≤100),代表有T组数据。
对于每组数据,第一行一个整数n(2≤n≤100),代表彩票中数字序列的位数。
第二行为一个长度为n的数字序列a1a2a3...an(0≤ai≤9)。
输出
如果这张彩票是幸运的,输出YES,否则输出NO。
样例输入
2
5
73452
4
1248
样例输出
YES
NO
提示
第一个样例:能分成3段,7、34和52,7=3+4=5+2。
第二个样例:不能分出。
思路:
需要注意两点:
1.对应的序列要连续,也不用交换位置啥的,只要连续就行
2.对应的分段要大于等于2
这个问题规模不算太大,只要段数大于等于2就行,那么可以直接按段的方式进行遍历即可
#include<iostream>
using namespace std;
int T;
int N;
const int MAXN =110;
char arr[MAXN];
int C(int num){
int level =0;
int sum = 0;
for(int i=0;i<N;i++){
int aa = arr[i] - '0';
if(sum+aa<num){
sum+=aa;
}else if(sum+aa>num){
return 0;
}else if(sum+aa==num){
sum =0;
level++;
}
}
return level;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&N);
int max_num = -1;
int sum = 0;
scanf("%s",arr);
// printf("%s\n",arr);
for(int i= 0 ;i<N;i++){
int aa = arr[i] - '0';
max_num = max(max_num,aa);
sum+=aa;
}
bool ok = false;
//从2开始遍历分段,得出每个段值的数,并进行计算即可
for(int i=2;i<=N;i++){
if(sum%i ==0){
int temp_sum = sum/i;
if(C(temp_sum)>=2) {
ok = true;
break;
}
}
}
if(ok)printf("YES\n");
else printf("NO\n");
}
return 0;
}