题解 | #切圈圈#

切圈圈

https://ac.nowcoder.com/acm/problem/220554

题意:对于一个保证 i=1nai=0\sum\limits_{i=1}^{n} a_i=0 的序列 {an}\{a_n\},求划分出的最大段数使得每一段区间和均为 00

考虑前缀和,对于一个区间 [l,r][l,r],如果 sl1=srs_{l-1}=s_r 代表区间和为 00

sl1=a1+a2++al1s_{l-1}=a_1+a_2+\cdots+a_{l-1}

sr=a1+a2++ars_{r}=a_1+a_2+\cdots+a_{r}

srsl1=al++ar\therefore s_{r}-s_{l-1}=a_l+\cdots+a_r

sl1=sr\because s_{l-1}=s_r

al++ar=0\therefore a_l+\cdots+a_r=0,得证。

有了这个结论,我们只需要数出前缀和数组中的众数即可,等于是把每一段都划分成这个众数既为 sl1s_{l-1} 又为 srs_r

环形和整个序列和为零的性质保证了这样做的正确性。

#include<map>
#include<cstdio>
int init(){
	char c = getchar();
	int x = 0, f = 1;
	for (; c < '0' || c > '9'; c = getchar())
		if (c == '-') f = -1;
	for (; c >= '0' && c <= '9'; c = getchar())
		x = (x << 1) + (x << 3) + (c ^ 48);
	return x * f;
}
void print(int x){
	if (x < 0) x = -x, putchar('-');
	if (x > 9) print(x / 10);
	putchar(x % 10 + '0');
}
int mx(int x, int y){
	return x > y ? x : y;
}
std::map<int, int>map;
int main(){
	int T = init();
	while (T--) {
        map.clear();
		int n = init(), ans = 0, max = 0;
		while (n--) {
			ans += init();
			max = mx(max, ++map[ans]);
		}
		print(max), putchar('\n');
	}
}
全部评论

相关推荐

2024-12-27 23:45
已编辑
三江学院 Java
程序员牛肉:死局。学历+无实习+项目比较简单一点。基本就代表失业了。 尤其是项目,功能点实在是太假了。而且提问点也很少。第一个项目中的使用jwt和threadlocal也可以作为亮点写出来嘛?第二个项目中的“后端使用restful风格”,“前端采用vue.JS”,“使用redis”也可以作为亮点嘛? 项目实在是太简单了,基本就是1+1=2的水平。而你目标投递的肯定也是小厂,可小厂哪里有什么培养制度,由于成本的问题,人家更希望你来能直接干活,所以你投小厂也很难投。基本就是死局,也不一定非要走后端这条路。可以再学一学后端之后走测试或者前端。 除此之外,不要相信任何付费改简历的。你这份简历没有改的必要了,先沉淀沉淀
点赞 评论 收藏
分享
评论
2
1
分享

创作者周榜

更多
牛客网
牛客企业服务