给定一个数n ,有一个数x , ( 1<=x<=n ) 每次你可以猜在[1,n]中的数,假设是y,如果x==y,游戏结束,如果没猜中,则告诉你gcd(x,y),然后继续猜,直到猜中为止。
现在问给定n的情况下,最坏情况下最少要多少次猜中
标签:
2 ≤ n ≤ 10000.
每次询问,相当于确定每个质数P是否出现。考虑到最坏情况,一定是问什么都回答1,否则的话就相当于把n缩小成了n/p。
问题就转换成了将1~n中间的质数分成K组,每组内的质数之积不大于n,求最小的k。
对于不小于$\sqrt n$的质数来说,他一定只能和小于$\sqrt n$的质数来配对,这样答案至少为不小于$\sqrt n$的质数个数。
而小于$\sqrt n$的质数的个数一定比不小于$\sqrt n$的质数的个数小很多,并且一定可以找到一个质数来配对。
所以问题的答案可以通过贪心来求,递减枚举每一个不小于质数,判断当前最小质数是否可以合并。
1 #include<cstdio> 2 #include<algorithm> 3 #define N 100010 4 using namespace std; 5 int n,prime[N],tot,ans; 6 bool vis[N]; 7 void pre() 8 { 9 for(int i=2;i<=n;i++) 10 { 11 if(!vis[i])prime[++tot]=i; 12 for(int j=1;j<=tot&&i*prime[j]<=n;j++) 13 { 14 vis[i*prime[j]]=1; 15 if(!(i%prime[j]))break; 16 } 17 } 18 } 19 int main() 20 { 21 scanf("%d",&n); 22 pre(); 23 for(int l=1,r=tot;l<=r;r--) 24 { 25 ans++; 26 int now=l,sum=prime[r]; 27 while(l<r&&sum*prime[l]<=n) 28 sum*=prime[l++]; 29 } 30 printf("%d\n",ans); 31 }
2632: [neerc2011]Gcd guessing game
标签:
原文地址:http://www.cnblogs.com/xuruifan/p/5608192.html