题目链接:http://poj.org/problem?id=3782
题意:将一个序列分区并使他们的和相等。
YY一下的方法:
#include<stdio.h>
int n;
int a[10000+10];
int find(int pos,int sum)
{
int i,s=0;
int mark=0;
for(i=pos;i<n;i++)
{
s+=a[i];
if(s==sum)
{
mark=i;
break;
}
if(s>sum || i==n-1)//当前和 比 sum大,或 查到最后(意味着没相等),返回-1
{
mark=-1;
break;
}
}
return mark;
}
int main()
{
int t,i;
int cas,mark;
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
mark=0;
scanf("%d %d",&cas,&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
int s=0,x;
for(i=0;i<n;i++)
{
s+=a[i]; //暴力,第一个开始加,遍历之后是否有相同和,
x=find(i+1,s);//遍历之后是否有相同和,有的话返回下表。没有就返回-1
while(x!=-1)
{
x=find(x+1,s);//继续向后找。
if(x==n-1) //找到最后。
{
mark=1;
break;
}
}
if(mark==1)
break;
}
printf("%d %d\n",cas,s);
}
}
return 0;
}
树状数组
#include<iostream>
#include<stdio.h>
#define MAX 5000*10+1
int n,c[MAX];
int A[MAX];
int lowbit(int x)
{
return x&(-x);
}
//树状数组中从x开始不断减lowbit(x)(即x&(-x))可以得到整个[1..x]的和,
//而从x开始不断加lowbit(x)则可以得到x的所有前趋。
int sum(int x)
{
int sum=0;
while(x>0)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void add(int x,int c) //将A[x]的值加上c;
{
for(int i=x;i<=n;i-=lowbit(i))
A[i]+=c;
}
void inster(int x,int i)
{
while(x<=n)
{
c[x]+=i;
x+=lowbit(x);//管辖之上的
}
}
int main()
{
int count,cas,i,t;
while(scanf("%d",&t)!=EOF)
{
count=0;
while(t--)
{
memset(c,0,sizeof(c));
scanf("%d %d",&cas,&n);
for(i=1;i<=n;i++)
{
scanf("%d",&A[i]);
inster(i,A[i]);
}
int ans,x,j,k;
for(i=1;i<=n;i++)
{
ans=sum(i)-sum(0);
k=i+1,j=k;
while(j<=n)
{
x=sum(j)-sum(k-1);
j++;
if(x>ans)
break;
if(x==ans)
{
k=j;
}
}
if(j==n+1 && x==ans)
break;
}
printf("%d %d\n",cas,ans);
}
}
return 0;
}