您的位置:首页 > 其它

Brunhilda的生日(brunhilda)

2015-10-02 23:14 531 查看

Brunhilda的生日(brunhilda)

题目描述

除去对铁质盔甲强烈的热爱,Brunhilda是一个正常的7岁女孩。近期,她正在策划一个完美的生日派对。她发明了如下的一个游戏:所有的孩子在一个数k被宣布之前不停地跑来跑去。当这个数字k宣布后,所有的孩子将形成人数为k的几个群体,且保证剩余的孩子数目小于k。最后,这不足k个的孩子将从游戏中被淘汰。紧接着,比赛将继续进行,并公布一个新的数字k。游戏将在所有的孩子都被淘汰后结束。

Brunhilda请她的父亲Wotan在游戏中来宣读数字。Wotan不喜欢这个游戏,当然也不希望在游戏的第一轮就宣布一个正无穷(–ps:宣布正无穷等于将所有的孩子都从游戏中淘汰)。 Brunhilda认为这在派对上是相当尴尬的情形,所以她给了她父亲一串总计m个素数的列表。这样,她的父亲便可以从中进行选择。

Wotan想尽快结束比赛,因为他有一张他最喜欢的足球俱乐部 FC Asgard的比赛门票。不幸的是,Brunhilda不知道派对上参加游戏的孩子数目。现在,对于Q个不同的数n1,…,nQ个儿童,Wotan要预先知道他所需宣读的最少数字,以便他尽早结束游戏。

输入

第一行包含整数m和Q。

第二行包含m个不同的递增素数pi(1≤i≤M),表示Wotan可以宣读的数字。

接下来Q行分别包含一个整数nj(1≤j≤Q),表示可能参加游戏的孩子数目nj。

输出

输出包括Q行。第j行表示对于询问nj所得到的答案,即如果Wotan能结束游戏,请输出他最少所需要宣读的数字个数,否则输出字符串oo(两个小写字母o表示∞)。

样例输入

2 2

2 3

5

6

样例输出

3

oo

提示

1、20%的数据:m,nj,Q<=10000. 此外20%的数据:Q=1

2、100%的数据:1<=m,Q<=100000,1<=nj<=10000000,2<=pi<=10000000

来源

Baltic2013

题解

对于任意一个数字,每次选择质数表中取模后的值最大的数显然是最优的,所以可以先预处理出每个数字在质数表中所能整除的最大质数,对于i+1<=j<=i+prime-1的数字,f[j]=f[i]+1,用队列维护使得效率o(n)(事实上与处理的效率是n(ln(n)),但也可以优化成o(n)).

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<queue>
#include<algorithm>
#define N 10000010
#define M 100010
#define inf 210000000
using namespace std;
int n,Q,ans,maxn,p[M],s[M],num
,f
,q
;
int main()
{
int x;
scanf("%d%d",&n,&Q);
for(int i=1;i<=n;i++)scanf("%d",&p[i]);
for(int i=1;i<=Q;i++)
scanf("%d",&s[i]),maxn=max(maxn,s[i]);
for(int i=1;i<=maxn;i++)f[i]=inf,num[i]=inf;
for(int i=1;i<=n;i++)
for(int j=p[i];j<=maxn;j+=p[i])num[j]=p[i];
int l=1,r=2,st=1;q[1]=0;f[0]=0;num[0]=p
;
while(l<r&&st<=maxn)
{
int x=q[l];l++;
if(num[x]==inf)continue;
int tmp=min(x+num[x]-1,maxn);
for(;st<=tmp;st++)f[st]=f[x]+1,q[r++]=st;
}
for(int i=1;i<=Q;i++)
{
if(f[s[i]]==inf)printf("oo\n");
else printf("%d\n",f[s[i]]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: