CF18C Stripe
https://www.luogu.com.cn/problem/CF18C
涉及知识点:模拟,枚举,前缀和
黄色题
涉及知识点:模拟,枚举,前缀和
黄色题
思路:看到要求出所有的方案,就想到能切割的点不止一个。这时,就可以通过枚举切割点,进而得到全部分割的可能方案,然后判断十分合法。最后统计出合法方案的数量即可。
代码:
#include <iostream> using namespace std; const int MAXN=100005; //题目中数组最大限制 int N; long long a[MAXN]={0}; long long s[MAXN]={0}; //前缀和数组 long long sum=0; //所有数的和,其实这个也可以用s[N]代替 int ans=0; //记录答案 int main() { cin>>N; for(int i=1;i<=N;i++) //要从1开始循环,不然会数组溢出 { cin>>a[i]; s[i]=s[i-1]+a[i]; //处理前缀和,即将上一个数的前缀和加上目前的数 sum+=a[i]; //加和 //cout<<s[i]<<" "; //调试用品,没有什么用 } for(int i=1;i<N;i++) { if(s[i]*2==sum) { //这里使用if(sum/s[i]==2)会炸 //判断是否符合条件 ans++; //如果符合条件,就将ans++ } } cout<<ans; //输出 return 0; //回家领糖吃咯 }
方法2:动态求和
#include<cstdio> using namespace std; const int N=1e5+50; int a[N]; int n;//定义数组,废话 int tot2; int tot1;//定义存储当前前段数列和与后段数列和的变量 int ans=0;//定义储存答案的变量 int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); if(i>1) { tot2+=a[i];//将1以后的数都加进tot2里面,作为第一个后段数列。 } } if(n==1) { printf("0"); return 0; } tot1+=a[1];//将a[1]加进tot1里面,作为第一个前段数列。 if(tot1==tot2)//得预先判断第一个前段数列与后段数列是否相等,不判断会很精彩 { ans++; } for(int i=2;i<=n-1;i++)//判断过了第一个,那就从第2个开始 { tot1+=a[i];//每次循环tot1加上a[i],以获得当前前段数列的和 tot2-=a[i];//每次循环tot2减去a[i],已获得当前后段数列的和 if(tot1==tot2)//如果两者相等 { ans++;//累加 } } printf("%d",ans);//完美输出~ return 0; }

浙公网安备 33010602011771号