1. 程式人生 > >2018焦作區域賽 E - Resistors in Parallel (Gym - 102028E) (數學+高精度)

2018焦作區域賽 E - Resistors in Parallel (Gym - 102028E) (數學+高精度)

In this physics problem, what we are concerned about are only resistors. If you are poor at physics, do not worry, since solving this problem does not require you to have advanced abilities in physics.

Resistors are said to be connected together in parallel when both of their terminals are respectively connected to each terminal of the other resistors.

We have the following parallel resistor equation for k resistors with resistances R1, R2, ..., Rk in parallel and their combined resistance R:

Now you have n resistors, the i-th of which has a resistance of ri ohms with the equation

You also have n

 selections, the i-th of which is a set of resistors Si such that

Please find a selection in which the resistors form a parallel resistor with the minimum resistance and output the reduced fraction  of its resistance.

Input

The input contains several test cases, and the first line contains a positive integer T

 indicating the number of test cases which is up to 100.

For each test case, the only one line contains an integer n, where 1 ≤ n ≤ 10100.

Output

For each test case, output a line containing a reduced fraction of the form p/q indicating the minimum possible resistance, where p and q should be positive numbers that are coprime.

Example

Input

3
10
100
1000

Output

1/2
5/12
35/96

題意:選一個小於等於n(10^100)的無平方因子的數,它的電阻阻值就是它的所有因子的倒數和的倒數,求這個最小的阻值。

思路:隊友(lzw巨佬)猜了一個結論:小於n的連續的素數之積就是滿足條件的,它的阻值就是因子倒數和的倒數,因為我們要儘可能使R1,R2……Rk最小,才能使他們的和最大,最後使答案最小。因為是資料特別大,所以我用的java。

import java.lang.reflect.Array;
import java.math.*;
import java.util.*;
public class Main {
	public static int[] getPrimes(int n) {
        int[] a = new int[n];
        for(int i = 2; i < n; i ++) {
            a[i] = i;
        }
        for(int i = 2; i < n; i ++) {
            if (a[i] != 0) {
                for(int j = i * 2; j < n; j = j + i) {
                    a[j] = 0;
                }
            }
        }
        int count = 0;
        for(int i = 2; i < n; i++) {
            if (a[i] != 0) {
                count ++;
            }
        }
        if (count > 0) {
            int[] primes  = new int[count];
            int j = 0;
            for (int i = 2; i < n; i ++) {
                if(a[i] != 0) {
                    primes[j] = a[i];
                    j ++;
                }
            }
            return primes;
        }
        return null;
    }
	public static BigInteger gcd(BigInteger a,BigInteger b) {
        if(b.compareTo(BigInteger.ZERO)==0)
            return a;
        else
            return gcd(b,a.remainder(b));
    }
	public static void main(String[] args) {
		int t;
		Scanner cin=new Scanner(System.in);
		int []prime =getPrimes(5000);
	/*	for(int i=0;i<Array.getLength(prime);i++)
		{
			System.out.println(prime[i]);
		}*/
		t=cin.nextInt();
		while(t--!=0)
		{
			BigInteger n=cin.nextBigInteger();
			int i;
			BigInteger sum=BigInteger.ONE,s=BigInteger.ONE;
			
			for( i=0;;i++)
			{
				if(sum.multiply(BigInteger.valueOf(prime[i])).compareTo(n)<=0)
				{
					sum=sum.multiply(BigInteger.valueOf(prime[i]));
					s=s.multiply(BigInteger.valueOf(prime[i]+1));
				}
				else 
					break;
			}
			BigInteger g=gcd(sum,s);
			s=s.divide(g);
			sum=sum.divide(g);
			System.out.println(sum+"/"+s);
		}
	}
}