poj之旅——2566,2739

来源:互联网 发布:办户外婚礼多少钱知乎 编辑:程序博客网 时间:2024/05/22 00:12

2566:从数列中找出连续序列,使得和的绝对值与目标数之差最小

2739:将一个整数分解为连续的素数之和,有多少种分法

题解:非常简单的尺取法解题即可。

参考程序:

2566:

#include<cstdio>#include<algorithm>#define maxn 110000#define INF 0x7f7f7f7fusing 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 11000using 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;elseif (sum==n)res++;sum-=form.prime[l++];}printf("%d\n",res);}return 0;}


0 0
原创粉丝点击