2566:从数列中找出连续序列,使得和的绝对值与目标数之差最小
2739:将一个整数分解为连续的素数之和,有多少种分法
题解:非常简单的尺取法解题即可。
参考程序:
2566:
#include<cstdio>
#include<algorithm>
#define maxn 110000
#define INF 0x7f7f7f7f
using namespace std;
struct P{
int sum,id;
bool operator < (P rhs)const{
return sum<rhs.sum;
}
/*
P(int sum,int id):sum(sum),id(id){}加上这句话,
就有no match for function P::P()的错误,明明在最短路时有同样的代码,为什么这里就过不了呢
请教路过大神
*/
}b[maxn];
int res,from,to,n,k;
int a[maxn];
void prepare(){
b[0].sum=0;
b[0].id=0;
for (int i=0;i<n;i++)
b[i+1].sum=b[i].sum+a[i],
b[i+1].id=i+1;
sort(b,b+1+n);
}
int next(int t,int l,int r){//枚举区间为(l,r]
if (l>=r)return -INF;
int now=b[r].sum-b[l].sum;
if (abs(res-t)>abs(now-t)){
res=now;
from=min(b[r].id,b[l].id);
to=max(b[r].id,b[l].id);
}
return now;
}
void solve(int num){
res=-INF;
int sum=-INF;
int front=0,back=0;
while (true){
while (back<n && sum<num)
sum=next(num,front,++back);
if (sum<num)break;
sum=next(num,++front,back);
}
printf("%d %d %d\n",res,from+1,to);
}
int main(){
while (scanf("%d%d",&n,&k)==2 && (n || k)){
for (int i=0;i<n;i++)scanf("%d",&a[i]);
prepare();
for (int Qu=0;Qu<k;Qu++){
int num;
scanf("%d",&num);
solve(num);
}
}
return 0;
}
2739:
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define maxn 11000
using namespace std;
int cnt;
struct Prime{
int n;
bool is[maxn];
int prime[maxn];
void make(){
n=maxn;
memset(is,1,sizeof(is));
is[0]=false;is[1]=false;
int m=(int)floor(sqrt((double)n)+0.5);
for (int i=2;i<=m;i++)
if (is[i])
for (int j=i*i;j<=n;j+=i)
is[j]=false;
for (int i=2;i<=n;i++)
if (is[i])prime[cnt++]=i;
}
}form;
int main(){
form.make();
int n;
while (scanf("%d",&n)==1 && n){
int l=0,r=0,sum=0,res=0;
for (;;){
while (sum<n && r<cnt)
sum+=form.prime[r++];
if (sum<n)break;
else
if (sum==n)res++;
sum-=form.prime[l++];
}
printf("%d\n",res);
}
return 0;
}