题目链接:http://lightoj.com/volume_showproblem.php?problem=1341
题意:给你地毯面积和最小可能边的长度,让你求有几种组合的可能。
题解:这题就厉害了。第一次了解了算术基本定理。
这里运用的是应用1。你想,你把所有的正因数个数找到了,减半,不就是组合对数了么QWQ。最后再减去小于最小的边的可能性。Perfect。数学真奇妙。
素数的板子是最开始贴的自己的那个。QWQ
1 #include<iostream> 2 #include<cmath> 3 #include<cstdio> 4 using namespace std; 5 #define ll long long 6 const int N = 1e6 + 10; 7 8 bool prime[N]; 9 int p[N],tot; 10 11 void init(){ 12 for(int i = 2 ; i < N ; i++){ 13 prime[i] = true; 14 } 15 for(int i = 2 ; i < N; i++){ 16 if(prime[i]) 17 p[tot++] = i; 18 for(int j = 0; j < tot && i * p[j] < N; j++){ 19 prime[ i*p[j] ] = false; 20 if( i % p[j] == 0) 21 break; 22 } 23 } 24 } 25 26 int main(){ 27 init(); 28 int T; 29 cin>>T; 30 int t = 1,ans = 1; 31 ll area , minline; 32 while(T--){ 33 cin>>area>>minline; 34 ans = 1; 35 if(minline >= sqrt(area)){ 36 printf("Case %d: %d ",t,0); 37 t++; 38 continue; 39 } 40 else{ 41 ll tmp = area; 42 43 //筛ai 44 for(int i = 0; i < tot && p[i] * p[i] <= area ; i++){ 45 int cnt = 0; 46 while( area % p[i] == 0){ 47 area /= p[i]; 48 cnt++; 49 } 50 ans *= (cnt + 1); //所有正因数的个数 51 } 52 53 54 if( area != 1){ 55 ans <<= 1; //减半 56 } 57 ans >>= 1; 58 for(int i = 1 ; i < minline; i++){ 59 if( tmp % i == 0) 60 ans--; //晒出小于minline的因子 61 } 62 printf("Case %d: %d ",t,ans); 63 t++; 64 } 65 66 } 67 68 69 return 0; 70 }