ural 1118
题目:http://acm.timus.ru/problem.aspx?space=1&num=1118
题意:给出个范围 n ~ m,定义 triviality(i) = ( i 的所有因子的和) / i ;
做了一晚上了,就是 WA 9 ,都快要哭了。当发现自己哪里错了时候,都想一头撞死了,我竟然把那个 所有因子和当成了因子个数来算,不仔细看题,教训。。白交了那么多次。
说一下注意点:1.如果给的范围内有 1,那么 1 的 triviality = 0(因为题目说了,n因子是小于n本身的)
2.如果给的范围内有素数,那么素数越大 他的triviality值就越小,所以只需找到那个最大素数就可以了
3.所求的数一定不是偶数(当然这个是个优化条件,不用也是没事的,就是耗时多点)
4.如果上三个条件都不满足,那么枚举每一个就行了,因为如果没有素数,那么范围也不会很大
View Code
1 View Code 2 typedef long long ll; 3 const int N = 1000010; 4 const double esp = 1e-9; 5 bool vis[N]; 6 ll ans; 7 void is_prime() // 标记素数 8 { 9 int i,j; 10 for(i = 2; i < N ;i++) 11 { 12 if(!vis[i]) 13 { 14 for(j = 2; j * i < N; j++) 15 { 16 if(vis[i * j]) continue; 17 vis[i * j] = true; 18 } 19 } 20 } 21 } 22 int main() 23 { 24 num = 0; 25 is_prime(); 26 vis[0] = true; 27 vis[1] = true; 28 int n,i,m; 29 while(scanf("%d%d",&n,&m) != EOF) 30 { 31 if(n == 1 || n == m) // 如果范围有 1 ,直接输出 32 { 33 printf("%d\n",n); 34 continue; 35 } 36 int flag = 0; 37 for(i = m; i >= n; i--) // 查找该范围内是否有素数,输出最大的 38 { 39 if(!vis[i]) {flag = 1;break;} 40 } 41 if(flag) 42 { 43 printf("%d\n",i); 44 continue; 45 } 46 double minn = 10000000,num,tem; 47 for(i = n; i <= m; i ++) // 挨个枚举 48 { 49 if(i % 2 == 0) continue; 50 res = 0; 51 for(int j = 2; j*j <= i; j ++) 52 { 53 if(i%j == 0) 54 { 55 tem = i/j; 56 num += tem+j; 57 if(tem == j) num -= tem; 58 } 59 } 60 num /= i*1.0; 61 if(num < minn) 62 { 63 minn = num; 64 flag = i; 65 } 66 } 67 printf("%d\n",flag); 68 } 69 return 0; 70 }