problem1 link
两个数字后面都有阶乘符号,可以抵消。
import java.util.*;
import java.math.*;
import static java.lang.Math.*;
public class ExtraordinarilyLarge {
public String compare(String x, String y) {
boolean both=false;
while(x.endsWith("!")&&y.endsWith("!")) {
x=x.substring(0,x.length()-1);
y=y.substring(0,y.length()-1);
both=true;
}
boolean bswap=false;
if(x.endsWith("!")) {
String t=new String(x);
x=y;
y=t;
bswap=true;
}
long xx=Long.valueOf(x);
if(xx==0&&both) {
xx=1;
}
long yy=1;
if(y.endsWith("!")) {
int id=y.indexOf("!");
yy=Long.valueOf(y.substring(0,id));
final int num=y.length()-id;
for(int i=0;i<num&&yy<=xx;++i) {
yy=cal(yy,xx);
}
}
else {
yy=Long.valueOf(y);
if(yy==0&&both) {
yy=1;
}
}
if(xx<yy) {
if(bswap) {
return "x>y";
}
return "x<y";
}
else if(xx==yy) {
return "x=y";
}
else {
if(bswap) {
return "x<y";
}
return "x>y";
}
}
long cal(long x,long y) {
if(x==0) {
return 1;
}
long result=1;
for(int i=2;i<=x;++i) {
if(result<=y/i) {
result=result*i;
}
else {
return y+1;
}
}
return result;
}
}
problem2 link
在一个有向无环图上进行dp即可。
import java.util.*;
import java.math.*;
import static java.lang.Math.*;
public class ContestSchedule {
public double expectedWinnings(String[] contests) {
final int n=contests.length;
int[][] p=new int[n][3];
for(int i=0;i<n;++i) {
String[] t=contests[i].split("\\W+");
assert t.length==3;
for(int j=0;j<3;++j) {
p[i][j]=Integer.valueOf(t[j]);
}
}
boolean[][] g=new boolean[n][n];
for(int i=0;i<n;++i) {
for(int j=0;j<n;++j) {
if(i==j) {
g[i][j]=false;
continue;
}
if(p[i][1]<=p[j][0]) {
g[i][j]=true;
}
else {
g[i][j]=false;
}
}
}
Queue<Integer> queue=new LinkedList<>();
double[] f=new double[n];
boolean[] inq=new boolean[n];
for(int i=0;i<n;++i) {
inq[i]=true;
f[i]=p[i][2]/100.0;
queue.offer(i);
}
while(!queue.isEmpty()) {
final int u=queue.poll();
inq[u]=false;
for(int i=0;i<n;++i) {
if(g[u][i]) {
final double c=p[i][2]/100.0;
if(f[u]+c>f[i]) {
f[i]=f[u]+c;
if(!inq[i]) {
inq[i]=true;
queue.offer(i);
}
}
}
}
}
double result=0;
for(int i=0;i<n;++i) {
result=Math.max(result,f[i]);
}
return result;
}
}
problem3 link
$n,m$中小的那个必定小于9.这样一行一行进行dp即可。
import com.sun.org.apache.xpath.internal.operations.Bool;
import java.util.*;
import java.math.*;
import static java.lang.Math.*;
public class SeatingPlan {
public String expectedTrial(int m, int n, int k) {
if(n<m) {
int x=m;
m=n;
n=x;
}
long[][][] f=new long[n+1][1<<m][k+1];
int[] num=new int[1<<m];
num[0]=0;
for(int i=1;i<(1<<m);++i) {
num[i]=num[i>>1]+(i&1);
}
List<List> g=new ArrayList<>();
for(int i=0;i<(1<<m);++i) {
List<Integer> list=new ArrayList<>();
if(((i>>1)&i)!=0) {
g.add(list);
continue;
}
for(int j=0;j<(1<<m);++j) {
if((i&j)==0&&((j>>1)&j)==0) {
list.add(j);
}
}
g.add(list);
}
f[0][0][0]=1;
for(int i=1;i<=n;++i) {
for(int j=0;j<(1<<m);++j) {
for(int t=0;t<=k;++t) {
if(0==f[i-1][j][t]) {
continue;
}
List list=g.get(j);
for(int p=0;p<list.size();++p) {
int s=(int)list.get(p);
if(t+num[s]>k) {
continue;
}
f[i][s][t+num[s]]+=f[i-1][j][t];
}
}
}
}
long result=0;
for(int i=0;i<(1<<m);++i) {
result+=f[n][i][k];
}
if(result==0) {
return "Impossible!";
}
BigInteger sum=BigInteger.ONE;
for(int i=1;i<=k;++i) {
sum=sum.multiply(int2biginteger(n*m-i+1)).divide(int2biginteger(i));
}
long s=Long.valueOf(sum.toString());
long p=gcd(result,s);
result/=p;
s/=p;
return Long.toString(s)+"/"+Long.toString(result);
}
static long gcd(long x,long y) {
return y==0?x:gcd(y,x%y);
}
static BigInteger int2biginteger(int x) {
return new BigInteger(Integer.toString(x));
}
}