Consider the error function F(x,y,z,n)=∣xn+yn−zn∣F(x,y,z,n)=∣xn+yn−zn∣, where ∣v∣∣v∣ means the absolute value of vv. Given two positive integers nn and zz, our problem is to find two positive integers xx and yy such that x<y<zx<y<z and the error value F(x,y,z,n)F(x,y,z,n) is minimized.
For example, if we are given n=3n=3 and z=9z=9, then the solution is: x=6x=6 and y=8y=8. This solution yields the error value 11.
Input
The first line contains the number of test cases T(T<10)T(T<10). Each subsequent line corresponds to a test case, which contains two positive integers n(2<n<10)n(2<n<10) and z(1<z<100000)z(1<z<100000).
Output
For each test case, output the value of xx, yy, and F(x,y,z,n)F(x,y,z,n) in a line, separated by spaces.
样例输入
2 3 9 3 7
样例输出
6 8 1 5 6 2
题目来源
找出F最小。
POINT:
大树+二分模拟。思路还是挺简单的。就是java写起来麻烦。另外可以打表的,比如一些重复用到的大树进行幂运算,打表处理。不然TLE。
import java.math.BigInteger;
import java.util.Scanner;
import java.math.*;
public class Main {
static BigInteger one = BigInteger.ONE;
static BigInteger zero = BigInteger.ZERO;
private static Scanner cin;
static BigInteger z;
static int n;
public static BigInteger qkm(int n,BigInteger base) {
BigInteger ans = one;
for(int i=1;i<=n;i++) {//这根本就不是快速幂!!
ans=ans.multiply(base);
}
return ans;
}
static BigInteger ans;
public static int check(int x,int y) {
BigInteger xx = BigInteger.valueOf(x);
BigInteger yy = BigInteger.valueOf(y);
ans = qkm(n, xx).add(qkm(n, yy)).subtract(qkm(n, z));
return ans.compareTo(zero);
}
public static void main(String args[]) {
cin = new Scanner(System.in);
int T=cin.nextInt();
while(T--!=0) {
n=cin.nextInt();
z=cin.nextBigInteger();
int ansx = 0,ansy=0;
BigInteger aim=BigInteger.valueOf(1);
for(int p=1;p<=100;p++) aim=aim.multiply(BigInteger.valueOf(10));
BigInteger inf = aim;
int num=0;
int l=1,rr=z.intValue()-1;
for(int i=rr;i>=1;i--) {
if(num>5000) break;
num++;
BigInteger fu=inf.multiply(BigInteger.valueOf(-1));
BigInteger zheng = inf;
l=1;
int r=i-1;
int fy=0,zy=0;
while(l<=r) {
int mid = (l+r)>>1;
if(check(i,mid)==-1) {
if(fu.compareTo(ans)==-1) {
fu=ans;
fy=mid;
}
l=mid+1;
}else if(check(i, mid)==0) {
zy=mid;
aim=zero;
break;
}else {
if(zheng.compareTo(ans)==1) {
zheng=ans;
zy=mid;
}
r=mid-1;
}
}
if(aim.compareTo(zero)==0) {
ansx=i;
ansy=zy;
break;
}
fu=fu.multiply(BigInteger.valueOf(-1));
if(aim.compareTo(fu)==1) {
aim=fu;
ansx=i;
ansy=fy;
num=0;
}
if(aim.compareTo(zheng)==1) {
aim=zheng;
ansx=i;
ansy=zy;
num=0;
}
}
if(ansx>ansy) {
int t=ansx;
ansx=ansy;
ansy=t;
}
System.out.println(ansx+" "+ansy+" "+aim);
}
}
}
第二个:
这个应该才是正确的。上面那个是把数据卡过了。
import java.math.BigInteger;
import java.util.Scanner;
import java.math.*;
public class Main {
static BigInteger one = BigInteger.ONE;
static BigInteger zero = BigInteger.ZERO;
static BigInteger haha;
static BigInteger z;
static int n;
public static BigInteger qkm(int n,BigInteger base) {
BigInteger ans = one;
while(n!=0) {
if(n%2==1)
ans=ans.multiply(base);
base=base.multiply(base);
n>>=1;
}
return ans;
}
static BigInteger ans;
static BigInteger xxx;
public static int check(int x,int y) {
BigInteger yy = BigInteger.valueOf(y);
ans = xxx.add(qkm(n, yy)).subtract(haha);
return ans.compareTo(zero);
}
public static void main(String args[]) {
Scanner cin = new Scanner(System.in);
int T=cin.nextInt();
while(T--!=0) {
n=cin.nextInt();
z=cin.nextBigInteger();
int ansx = 0,ansy=0;
BigInteger aim=BigInteger.valueOf(1);
for(int p=1;p<=100;p++) aim=aim.multiply(BigInteger.valueOf(10));
BigInteger inf = aim;
haha=qkm(n, z);
int l=1,rr=z.intValue()-1;
for(int i=rr;i>=1;i--) {
xxx=qkm(n,BigInteger.valueOf(i));
BigInteger fu=inf.multiply(BigInteger.valueOf(-1));
BigInteger zheng = inf;
l=1;
int r=i-1;
int fy=0,zy=0;
while(l<=r) {
int mid = (l+r)>>1;
if(check(i,mid)==-1) {
if(fu.compareTo(ans)==-1) {
fu=ans;
fy=mid;
}
l=mid+1;
}else if(check(i, mid)==0) {
zy=mid;
aim=zero;
break;
}else {
if(zheng.compareTo(ans)==1) {
zheng=ans;
zy=mid;
}
r=mid-1;
}
}
if(aim.compareTo(zero)==0) {
ansx=i;
ansy=zy;
aim=zero;
break;
}
fu=fu.multiply(BigInteger.valueOf(-1));
if(aim.compareTo(fu)==1) {
aim=fu;
ansx=i;
ansy=fy;
}
if(aim.compareTo(zheng)==1) {
aim=zheng;
ansx=i;
ansy=zy;
}
}
if(ansx>ansy) {
int t=ansx;
ansx=ansy;
ansy=t;
}
System.out.println(ansx+" "+ansy+" "+aim);
}
}
}