[FZYZOJ 1002] 雨天

P1002 -- 雨天

时间限制:1000MS      内存限制:65536KB无   无

Description

规则是这样的:每位姿迷可以抽到一张奖券。奖券上写有1到M这M个自然数。姿迷可以在这M个数中任意选取N个不同的数打圈。每个姿迷只能买一张奖券,不同的奖券上的选择不同。

每次抽奖将抽出两个自然数X和Y。如果某人拿到的奖券上,所选N个自然数的倒数和,恰好等于X/Y,则他将免费获得一张CD《My Story Your Song》。 现在,已知抽奖结果X和Y。作为燕姿的fans,你的任务是:求出必须准备多少CD,才能保证支付所有获奖者。 对于所有数据,N<=12,M<=60 X<=25,Y<=25 且对于同一种选数,syz只用支付一盘CD

Input Format

输入有且仅有一行,就是用空格分开的四个整数N,M,X,Y。

Output Format

输出有且仅有一行,即所需准备的CD数量。

Sample Input

2 4 3 4

Sample Output

1

Hint

好题!

【题解】

看到本题n、m、x、y都十分小,所以不需要使用分数类,直接用double,注意精度问题,判断相等用1e-9作为标准。

而且呢,还可以直接搜索,但是原本搜索的时间复杂度的max为C(60,12),但是我们可以加入如下剪枝:

1. 如果当前得到的数已经比x/y大,那么return

2. 如果当前得到的数加上最大的数乘还剩下选的次数仍比x/y,那么return

3. 如果当前得到的数加上最小的数乘还剩下选的次数仍比x/y,那么return

第4条,也是重要的一条,大神讲的:

4. 假设当前总和为a/b(a,b互质),那么a/b+1/p=(ap+b)/(bp),可知p一定会留在分母不能被约去,因为b一定不小于2,所以当p为比25大的质数时,1/p一旦被加入总和,分母便一定大于25,超过了题目y的范围。我们可以不予考虑这些质数;

然后根据神牛的指导,发现了一些规律,呈现在代码里了

= =其实我也没有弄懂|||

然后就AC了,0.107s,还排前几名。orz

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 double tar;
 4 double eps = 1e-9;
 5 double minuseps = -eps;
 6 bool used[61];
 7 int cnt=0;
 8 int n,m,x,y;
 9 inline double fabs(double a) {return a>0?a:-a;}
10 void tryy(int step, double now, int last) {
11     //cout<<step<<' '<<now<<' '<<last<<endl; 
12     if (step == n+1) {
13         if (now<=eps&&now>=minuseps) cnt++;
14         return ;
15     }
16     if (now <= minuseps) return;
17     if (now - (n-step+1)*1.0/(last+1) >= eps) return; //printf("1");
18     if (now - (n-step+1)*1.0/m <= minuseps) return; //printf("1");
19     for (int i=last+1;i<=m;++i) if(used[i]) tryy(step+1, now-1.0/i, i);
20     //printf("1");
21 }
22 int main() {
23     scanf("%d%d%d%d",&n,&m,&x,&y);
24     tar=1.0*x/y;
25     memset(used,0,sizeof(used));
26     for (int i=2;i<=sqrt(m);++i)
27         if(!used[i]) for (int j=i*2;j<=m;j+=i) used[j]=1;
28     for (int i=1;i<=11;++i) used[i]=true;
29     used[25]=used[26]=used[27]=used[32]=used[34]=used[38]=used[39]=used[44]=used[46]=used[49]=used[50]=0;
30     tryy(1,tar,0);
31     printf("%d\n",cnt);
32     return 0;
33 }
View Code
posted @ 2015-05-30 16:30  TonyFang  阅读(329)  评论(0编辑  收藏  举报