20140925 【 初等数论--欧拉函数 】 UVa 10214 - Trees in a Wood

14 篇文章 0 订阅
3 篇文章 0 订阅

Problem H
Trees in a Wood.
Input: Standard Input
Output: Standard Output
Time Limit: 10 seconds

Background

The saying ``You can't see the wood for the trees'' is not only a cliche, but is also incorrect. The real problem is that you can't see the trees for the wood. If you stand in the middle of a wood, the trees tend to obscure each other and the number of distinct trees you can actually see is quite small. This is especially true if the trees are planted in rows and columns, because they tend to line up. The purpose of this problem is to find how many distinct trees one can see if one were standing on the position of a tree in the middle of the wood.

The Problem

For a mathematically more precise description we assume that you are situated at the origin of a coordinate system in the plane.

Trees are planted at all positions , with |x|<=a and |y|<=b.

A tree at position (x,y) can be seen from the origin if there are no other trees on the straight line from (0,0) to (x,y). Find the number Kof all the trees in the wood that can be seen from the origin and the number N of all the trees to compute the fraction .

Hint: The Euler phi function is defined to be the number of integers m in the range 1≤m≤n relatively prime to n:

Instead of counting (an adequate method for small n!) you could as well use the following identity:

Hint: Remember that gcd(m,n)=gcd(m+n,n)=gcd(m+2n,n)=gcd(m+in,i)

You might be surprised that the fraction converges to 0.607927 for an infinitely large wood.

The Input

Each scenario consists of a line with the two numbers a and b (separated by a white space), with 1 <= a <= 2000 and 1 <= b <= 2000000 Input is terminated by a line with two zeros.

The Output

For each scenario print a line containing the fraction with a precision of 7 digits after the decimal point. Error less than 2e-7 or 2*10^(-7) will be tolerated.

Sample Input

3 2
0 0

Sample Output

0.7058824

Collected from TUD Programming Contest













#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <iterator>
using namespace std;
#define LL long long
const int maxN = 2000 + 10;
const int maxM = 2000000 + 10;

int n, m;

int gcd(int a, int b){
    return b ? gcd(b, a%b) : a;
}

int phi[maxM];
void phi_table(int n){
    memset(phi, 0, sizeof(phi));
    phi[1] = 1;
    for(int i=2; i<=n; i++)
        if( !phi[i] )
            for(int j=i; j<=n; j+=i){
                if( !phi[j] )   phi[j] = j;
                phi[j] = phi[j]/i*(i-1);
            }
}

int main(){     //freopen("1.in", "r", stdin);
    phi_table(maxM-5);
    while( EOF != scanf("%d%d", &n, &m) ){
        if( !n && !m )  break;
        if( n>m )   swap(n, m);
        double son=0.0, mo=(double)(2*n+1)*(2*m+1)-1;
        for(int i=1; i<=n; i++){
            son += phi[i]*(m/i);
            int k = m%i;
            for(int j=1; j<=k; j++)
                if( 1==gcd(j, i) )  son += 1;
        }
        son = (son+1)*4;
        printf("%.7lf\n", son/mo);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值