Bipartite + high precision -- Poj 2109 Power of Cryptography (reason why the double open n method passes)

Source: Internet
Author: User

Power of Cryptography
Time Limit: 1000 MS Memory Limit: 30000 K
Total Submissions: 14584 Accepted: 7412
Description
Current work in cryptography involves (among other things) large prime numbers and computing powers of numbers among these primes. work in this area has resulted in the practical use of results from number theory and other branches of mathematics once considered to be only of theoretical interest.
This problem involves the efficient computation of integer roots of numbers.
Given an integer n> = 1 and an integer p> = 1 you have to write a program that determines the n th positive root of p. in this problem, given such integers n and p, p will always be of the form k to the nth. power, for an integer k (this integer is what your program must find ).
Input
The input consists of a sequence of integer pairs n and p with each integer on a line by itself. for all such pairs 1 <= n <= 200, 1 <= p <10101 and there exists an integer k, 1 <= k <= 109 such that kn = p.
Output
For each integer pair n and p the value k shoshould be printed, I. e., the number k such that k n = p.
Sample Input
2 16
3 27
7 4357186184021382204544
Sample Output
4
3
1234

If you just want to know why the double open n method is passed, skip this section.
Question:
Evaluate an integer k so that k satisfies kn = p.
Ideas:
Because the p value is large and exceeds the range indicated by the basic data type, the kn is calculated using the multiplication of large numbers. When k-n = p, obtain the result (I don't know if I can open the nth power of a large number ...). How should we obtain the K value? According to the relationship between n and p, the number of digits in k can be determined. For example, n = 7, p = 4357186184021382204544, and p is 22. The result is rounded up with 22/7, obtain 4, that is, the number of digits of k, that is, the value range of k is 1000 ~ 9999. In this range, perform binary search to find the K value that meets the condition. ("There exists an integer k, 1 <= k <= 109, such that kn = p.", in fact... Make fun of you !)
# Include <stdio. h>
# Include <string. h>
# Include <math. h>

# Define LENGTH 110
# Define last length-2
# Define GREATER 1
# Define EQUAL 0
# Define LESS-1

// Multiply large Integers
Char * IntegerMultiplication (const char * a, const char * B, char * product)
{
Int I, j, k = LAST, first, value, temp [LENGTH];
Memset (temp, 0, sizeof (temp ));
For (I = strlen (a)-1; I> = 0; I --)
{
First = k --;
Value = a [I]-'0 ';
For (j = strlen (B)-1; j> = 0; j --)
{
Temp [first --] + = value * (B [j]-'0 ');
}
}
For (I = LAST; I> = first; I --)
{
Product [I] = temp [I] % 10 + '0 ';
Temp [I-1] + = temp [I]/10;
}
While (product [first] = '0' & first <LAST)
{
First ++;
}
Return & product [first];
}

// Compare the values of two strings
Int Compare (char * numA, char * numB)
{
// Remove the leading '0'
For (; * numA = '0'; numA ++ );
For (; * numB = '0'; numB ++ );
Int lenNumA = strlen (numA );
Int lenNumB = strlen (numB );
If (lenNumA = lenNumB)
{
Return strcmp (numA, numB );
}
If (lenNumA> lenNumB)
{
Return GREATER;
}
Return LESS;
}

// Obtain base ^ exp and store the result in res. pRes points to the first digit of the result.
Char * Power (char * base, int exp, char * res)
{
Res [LAST] = '1 ';
Char * pRes = & res [LAST], * temp = base;
While (exp! = 0)
{
If (exp % 2 = 1)
{
PRes = IntegerMultiplication (base, pRes, res );
}
Exp/= 2;
If (exp! = 0)
{
Base = IntegerMultiplication (base, base, temp );
}
}
Return pRes;
}

Int main (void)
{
Char p [LENGTH], res [LENGTH], cMid [LENGTH];
Unsigned int n, lenP, lenRoot, I, min, max, mid;
 
While (scanf ("% d % s", & n, & p )! = EOF)
{
// Obtain the min and max values in the k range based on the multiples of n and p.
LenP = strlen (p );
LenRoot = (int) ceil (double) lenP/n );
For (I = 1, min = 1; I <lenRoot; I ++)
{
Min * = 10;
}
For (I = 1, max = 9; I <lenRoot; I ++)
{
Max * = 10;
Max + = 9;
}

// Search for K value using the binary method
Bool finish = false;
While (! Finish)
{
Mid = (min + max)/2;
If (min> = max)
{
Break;
}
Sprintf (cMid, "% d", mid );
Memset (res, 0, sizeof (res ));
Switch (Compare (Power (cMid, n, res), p ))
{
Case LESS: min = mid + 1; break;
Case EQUAL: finish = true; break;
Case GREATER: max = mid-1; break;
Default: break;
}
}
// The data given by the question may not meet k ^ n = p
// The following is to obtain the largest k, satisfying k ^ n <= p
Sprintf (cMid, "% d", mid );
If (Compare (Power (cMid, n, res), p) = GREATER)
{
Mid --;
}
Printf ("% d \ n", mid );
}
Return 0;
}

Reason why the double open n method is passed
The following section of the program can also pass this question.
# Include <stdio. h>
# Include <math. h>

Int main (void)
{
Double n, p;
While (scanf ("% lf", & n, & p )! = EOF)
{
Printf ("%. 0lf \ n", pow (p, 1/n ));
}
Return 0;
}

First, the data strength in the question is not weak, which is indeed as stated in the question: "For all such pairs 1 <= n <= 200, 1 <= p <10101, so, the double type cannot accurately represent the given data, but can represent an approximate value.
When it is stored in a double variable
4357186184021382204544
And then output the following information:
4357186184021382000000
The value of the last six digits is changed to 0, which is quite different from that of the int variable. That is to say, when the value stored in the double type variable exceeds its precision expression range, the low data will be truncated. (About the representation of floating point numbers in the computer, Baidu... I am very clear about it .)
In this question, if the test data is:
7 4357186184021382204544
In fact, the processed data is:
7 4357186184021382000000
The result of 4357186184021382000000 power-7 is naturally 1234.
Why not 1233 or 1235?
12337 = 4332529576639313702577
12347 = 4357186184021382204544
12357 = 4381962969567270546875
It can be seen that the three values in the precision range expressed by the double type are different.
Therefore, the test data in this question is similar to the above situation, so we can use the double open n method.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.