E - Cup 2(dfs)

E - Cup 2
Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu
Submit Status

Description

The European Cup final is coming. The past two World Cup winners, Spain and Italy, will contest the decider at Kiev's Olympic Stadium. Italy-Spain Euro final promises to be clash of polar opposites, so it's difficult to say which team will win.

Now there are M fans in ZJU, N of them support Italy. Suppose you are the president of the students' union and you support Italy. You can divide these M fans into s1 groups(Level 1). More than half of the group(Level 1) support Italy ,than you can say it seems all the M fans support Italy. You can also divide each group(Level 1) into s2 groups(Level 2). More than half of the group(Level 2) support Italy ,than you can say this group(Level 1) support Italy. ... .You can also divide each group(Level i) into s(i+1) groups(Level i+1). More than half of the group(Level i+1) support Italy ,than you can say this group(Level i) support Italy. To be fair, every group(Level i) has the same number of person. Can you find an suitable way to arrange these N person so that all these M fans seem to support Italy.

Input

Mutiple test cases, process to the end of file.
Each case has a single line with two integer M , N (1<=M,N<=100000000).

Output

For each case:
The firt line output Yes if you can do the task or No for not. The second line output the minimum person you need.

Sample Input

4 3
12 5

Sample Output

Yes
3
No
6

题意:有n个人他们分在一组,如果其中支持意大利队球迷多于一半,那么这组就是一个合法组,同时我们可以说这n个人都支持意大利队。如果这n个人所在的组是非法组,那么你可以把这组继续平均拆分。比如拆成m组(每组中的人数相等),如果这m组中一半以上是合法组那么这n个人所在组依然算是合法组。题目的规则就是这样。问:给你M个人其中有N个意大利队球迷,能不能满足条件,使得我们可以说这M个人都是支持意大利的,并输出最少需要多少个意大利球迷在这M个人中。

思路: 对于n个人,我们只需求出最小的球迷数Minsgin和m比较下就能得出答案。而求Minsgin可以dfs记忆化搜一下,把n的所有可能分组情况遍历一遍。

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cstdlib>
 6 #include<map>
 7 using namespace std;
 8 
 9 map<int,int>kiss;
10 
11 int dfs(int n)
12 {
13     if(kiss.count(n)){//已经进行过计算,则直接返回值即可
14         return kiss[n];
15     }
16     int minsgin=n/2+1;//先初始化最小值,这应该是各种分法中最小值最大的一种分法
17     for(int i=2;i*i<=n;i++){
18         if(n%i==0){
19             minsgin=min(minsgin,(n/i/2+1)*dfs(i));//进行递归运算,分成n/i组,每组i个人
20             minsgin=min(minsgin,(i/2+1)*dfs(n/i));//分成i组,每组n/i个人;
21         }
22     }
23     kiss[n]=minsgin;//返回求出的最小值
24     return minsgin;
25 }
26 
27 
28 int main()
29 {
30     int n;
31     while(scanf("%d",&n)==1){//进行数据的输入
32         int m;
33         scanf("%d",&m);
34         int sgin=dfs(n);
35         if(sgin<=m){
36             printf("Yes\n%d\n",sgin);
37         }
38         else{
39             printf("No\n%d\n",sgin);
40         }
41     }
42     return 0;
43 }
View Code

 

 

 

posted @ 2013-12-03 10:07  秋心无波  阅读(217)  评论(0编辑  收藏  举报