此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。
题目链接(vjudge):https://vjudge.net/problem/UVA-12716
题目大意:
输入一个数字t,表示数据组数。
接下来t行,每行给出一个整数n(1<=n<=30000000),问有多少对整数a,b(1<=b<=a<=n),满足gcd(a,b) = a^b。
对于每个n,输出Case x: y,表示当前是第x组数据,结果是y。
Sample Input
2
7
20000000
Sample Output
Case 1: 4
Case 2: 34866117
分析:
详见《算法竞赛入门经典》P318
最普遍的想法就是写一个暴力,二重循环a,b枚举出所有的可能解。
尝试输出a,b和gcd(a,b)(设为c)的值,会发现c = a-b.
于是就可以只枚举a和c,算出b,再判断a^b是否等于c.
注意要把c放在外重循环,a放在内重循环。
AC代码:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 #include<cstring> 5 6 const int MAXN = 30000005; 7 8 int gcd(int a,int b) 9 { 10 if(b == 0) return a; 11 return gcd(b,a%b); 12 } 13 14 int cnt,tmp,mx,ans,t,n[MAXN],f[MAXN]; 15 16 int main() 17 { 18 // freopen("1.txt","r",stdin); 19 scanf("%d",&t); 20 for(int i = 1;i <= t;++ i){ 21 scanf("%d",&n[i]); 22 if(n[i] > mx) mx = n[i]; 23 } 24 for(int i = 1;i <= mx/2;++ i) 25 for(int j = i+i;j <= mx;j += i) 26 if((j^(j-i)) == i) 27 f[j] ++; 28 for(int j = 2;j <= mx;++ j) 29 f[j] += f[j-1]; 30 for(int i = 1;i <= t;++ i) 31 printf("Case %d: %d\n",i,f[n[i]]); 32 return 0; 33 }
时间: 2024-10-30 20:53:04