ACM ICPC 2011-2012 Northeastern European Regional Contest(NEERC)G GCD Guessing Game
G:
要你去才Paul的年龄,Paul的年龄在1~n之间,你每猜一个Paul会告诉你,你猜的这个数和他年龄的gcd,问在最坏情况下最少要猜多少次。
题解:
什么是最坏情况,我们直到如果他的年龄是1的话, 你需要猜一边全部素数。所以很明显这就是最坏情况,
如果p,q是素数,p*q<=n, 我们就可以猜p*q,一次就可以去掉两个素数了。
所以这一题就变成了将1~n的素数分成m部分, 每一部分的乘积要小于等于n。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <string> 6 #include <algorithm> 7 #include <cmath> 8 #include <ctime> 9 #include <vector> 10 #include <queue> 11 #include <map> 12 #include <stack> 13 #include <set> 14 using namespace std; 15 typedef long long LL; 16 typedef unsigned long long uLL; 17 #define ms(a, b) memset(a, b, sizeof(a)) 18 #define pb push_back 19 #define mp make_pair 20 #define eps 0.0000000001 21 #define IOS ios::sync_with_stdio(0);cin.tie(0); 22 #define random(a, b) rand()*rand()%(b-a+1)+a 23 const LL INF = 0x3f3f3f3f3f3f3f3f; 24 const int inf = 0x3f3f3f3f; 25 const int maxn = 10000+10; 26 const int mod = 1e9+7; 27 int prime[maxn]; 28 int main() { 29 #ifdef LOCAL 30 freopen("input.txt", "r", stdin); 31 // freopen("output.txt", "w", stdout); 32 #endif 33 34 35 freopen("gcd.in", "r", stdin); 36 freopen("gcd.out", "w", stdout); 37 // IOS 38 int n; 39 scanf("%d", &n); 40 ms(prime, 0); 41 for(int i = 2;i<=n;i++){ 42 if(!prime[i]) prime[++prime[0]] = i; 43 for(int j = 1;j<=prime[0]&&prime[j]<=n/i;j++){ 44 prime[prime[j]*i] = 1; 45 if(i%prime[j]==0) break; 46 } 47 } 48 int L = 1, R = prime[0]; 49 int ans = 0; 50 while(L<=R){ 51 int p = prime[R]; 52 while(prime[L]*p<=n){ 53 p *= prime[L]; 54 L++; 55 } 56 ans++; 57 R--; 58 } 59 printf("%d\n", ans); 60 return 0; 61 }