topcoder srm 425 div1

problem1 link

暴力搜索即可。

problem2 link

可以将每次所有的piece的位置看作一个状态,由于$C_{25}^{5}=53130$,所以最多有这么多状态。这里可以加一些优化来减少状态。比如通过旋转或者翻转是一样的状态其结果是一样的。

然后进行bfs即可。

problem3 link

对于一个状态$mask$来说,可以将其分成两个子状态$S_{1},S_{2}=mask-S_{1}$.为了防止重复,可以令两个固定的点$u_{1} \in S_{1},v_{1} \in S_{2}$.

$S_{1}={u_{1},u_{2},...,u_{n}}$

$S_{2}={v_{1},v_{2},...,v_{m}}$

那么$f[mask]=f[S_{1}]*f[S_{2}]*X*Y$

$X=\sum_{i=1}^{m}(p_{u_{1},v_{i}}*\sum_{x \in{S2-v_{i}}}(1-p_{u_{1},x}))$

$Y=\prod_{i=2}^{n}\prod _{x\in S_{2}}(1-p_{u_{i},x})$

 code for ploblem1

import java.util.*;
import java.math.*;
import static java.lang.Math.*;

public class CrazyBot {

	boolean[][] f=null;
	double[] p=new double[4];
	final int[] dx={0,0,-1,1};
	final int[] dy={1,-1,0,0};
	double result=0.0;
	int n;

	public double getProbability(int n, int east, int west, int south, int north) {
		this.n=n;
		f=new boolean[2*n+1][2*n+1];
		p[0]=east/100.0;
		p[1]=west/100.0;
		p[2]=south/100.0;
		p[3]=north/100.0;
		dfs(n,n,0,1.0);
		return result;
	}

	void dfs(int x,int y,int step,double prob) {
		if(step==n) {
			result+=prob;
			return;
		}
		f[x][y]=true;
		for(int i=0;i<4;++i) {
			int xx=x+dx[i];
			int yy=y+dy[i];
			if(!f[xx][yy]) {
				dfs(xx,yy,step+1,prob*p[i]);
			}
		}
		f[x][y]=false;
	}
}

  

code for ploblem2

import com.sun.org.apache.xpath.internal.operations.Bool;

import java.net.Inet4Address;
import java.util.*;
import java.math.*;
import java.util.regex.Pattern;

import static java.lang.Math.*;

public class PiecesMover {


	static class Pair {
		public int x;
		public int y;

		public Pair() {}
		public Pair(int x,int y){
			this.x=x;
			this.y=y;
		}
	}

	int index(int x,int y) {
		return x*5+y;
	}
	int index(Pair p) {
		return p.x*5+p.y;
	}
	Pair revIndex(int t) {
		return new Pair(t/5,t%5);
	}

	Map<Integer,Integer> map=new HashMap<>();
	Map<Integer,Integer> map1=new HashMap<>();
	List<Integer> map2=new ArrayList<>();
	List<Boolean> stopStatus=new ArrayList<>();
	int n=0;
	public int getMinimumMoves(String[] board) {
		int startMask=0;
		for(int i=0;i<5;++i) {
			for(int j=0;j<5;++j) {
				if(board[i].charAt(j)=='*') {
					startMask|=1<<index(i,j);
					++n;
				}
			}
		}
		if(n==1) {
			return 0;
		}

		Pair[] all=new Pair[n];
		for(int i=0;i<n;++i) {
			all[i]=new Pair();
		}
		dfs(0,0,0,0,all);

		return bfs(startMask);
	}

	int bfs(int startMask) {
		int[] f=new int[map2.size()];
		boolean[] inq=new boolean[map2.size()];
		for(int i=0;i<f.length;++i) {
			f[i]=-1;
		}

		startMask=map.get(startMask);
		Queue<Integer> queue=new LinkedList<>();
		int id=map1.get(startMask);
		queue.offer(id);
		f[id]=0;
		inq[id]=true;
		int result=1<<20;

		final int[] dx={0,0,1,-1};
		final int[] dy={1,-1,0,0};

		while(!queue.isEmpty()) {
			final int u=queue.poll();
			inq[u]=false;
			if(stopStatus.get(u)) {
				result=Math.min(result,f[u]);
				continue;
			}
			final int mask=map2.get(u);
			for(int i=0,num=0;i<25&&num<n;++i) {
				if((mask&(1<<i))==0) {
					continue;
				}
				++num;
				final int xx=revIndex(i).x;
				final int yy=revIndex(i).y;
				for(int d=0;d<4;++d) {
					final int nx=xx+dx[d];
					final int ny=yy+dy[d];
					if(nx<0||nx>=5||ny<0||ny>=5||(mask&(1<<index(nx,ny)))!=0) {
						continue;
					}
					final int nMask=map.get(mask^(1<<i)|(1<<index(nx,ny)));
					final int v=map1.get(nMask);
					if(f[v]==-1||f[u]+1<f[v]) {
						f[v]=f[u]+1;
						if(!inq[v]) {
							inq[v]=true;
							queue.offer(v);
						}
					}
				}
			}
		}
		return result;
	}

	void dfs(int x,int y,int id,int mask,Pair[] all) {
		if(id==n) {
			deal(mask,all);
			return;
		}
		if(y==5) {
			y=0;
			++x;
		}
		if(x==5) {
			return;
		}
		all[id].x=x;
		all[id].y=y;
		dfs(x,y+1,id+1,mask|1<<index(x,y),all);
		dfs(x,y+1,id,mask,all);
	}

	int getMaks(Pair[] p) {
		int mask=0;
		for(int i=0;i<p.length;++i) {
			mask|=1<<index(p[i]);
		}
		return mask;
	}

	void deal(int mask,Pair[] all) {
		if(map.containsKey(mask)) {
			return;
		}
		int[] tMask=new int[6];
		tMask[0]=reverseX(all);
		tMask[1]=reverseY(all);
		for(int i=0;i<4;++i) {
			all=rotate(all);
			tMask[i+2]=getMaks(all);
		}
		int minMask=tMask[0];
		for(int i=1;i<6;++i) {
			minMask=Math.min(minMask,tMask[i]);
		}
		map1.put(minMask,map2.size());
		for(int i=0;i<6;++i) {
			map.put(tMask[i],minMask);
		}
		map2.add(minMask);
		stopStatus.add(isStopStatus(all));
	}

	boolean isStopStatus(Pair[] all) {

		int t=1;
		List<Integer> list=new ArrayList<>();
		list.add(0);
		while(list.size()>0) {
			List<Integer> list1=new ArrayList<>();
			for(int i=0;i<all.length;++i) {
				if((t&(1<<i))!=0) {
					continue;
				}
				for(int j=0;j<list.size();++j) {
					if(isAdj(all[i],all[list.get(j)])) {
						list1.add(i);
						t|=1<<i;
						break;
					}
				}
			}
			list=list1;
		}
		return t==((1<<all.length)-1);
	}

	boolean isAdj(Pair a,Pair b) {
		if(a.x==b.x) {
			return Math.abs(a.y-b.y)<=1;
		}
		if(b.y==a.y) {
			return Math.abs(a.x-b.x)<=1;
		}
		return false;
	}

	int reverseX(Pair[] all) {
		int mask=0;
		for(int i=0;i<all.length;++i) {
			mask|=1<<index(all[i].x,4-all[i].y);
		}
		return mask;
	}
	int reverseY(Pair[] all) {
		int mask=0;
		for(int i=0;i<all.length;++i) {
			mask|=1<<index(4-all[i].x,all[i].y);
		}
		return mask;
	}
	Pair[] rotate(Pair[] all) {
		for(int i=0;i<all.length;++i) {
			int x=all[i].x;
			int y=all[i].y;
			all[i].x=4-y;
			all[i].y=x;
		}
		return all;
	}
}

  

code for ploblem3

import java.util.*;
import java.math.*;
import static java.lang.Math.*;

public class RoadsOfKingdom {


	double[][] prob=null;
	int n;

	double[][] f1=null;
	double[][] f2=null;
	boolean[] visited=null;
	double[] dp=null;

	public double getProbability(String[] roads) {
		n=roads.length;
		prob=new double[n][n];
		for(int i=0;i<n;++i) {
			for(int j=0;j<n;++j) {
				prob[i][j]=(roads[i].charAt(j)-'0')/8.0;
			}
		}
		f1=new double[1<<n][n];
		f2=new double[1<<n][n];
		for(int i=0;i<(1<<n);++i) {
			for(int j=0;j<n;++j) {
				f1[i][j]=1;
				f2[i][j]=0;
				for(int k=0;k<n;++k) {
					if((i&(1<<k))!=0) {
						f1[i][j]*=1-prob[k][j];
						f2[i][j]+=f1[i^(1<<k)][j]*prob[j][k];
					}
				}
			}
		}
		visited=new boolean[1<<n];
		dp=new double[1<<n];
		return dfs((1<<n)-1);
	}
	double dfs(int mask) {
		if(visited[mask]) {
			return dp[mask];
		}
		int p1=-1,p2=-1;
		for(int i=0;i<n;++i) {
			if((mask&(1<<i))!=0) {
				if(p1==-1) {
					p1=i;
				}
				else if(p2==-1) {
					p2=i;
					break;
				}
			}
		}
		if(p2==-1) {
			return 1;
		}
		final int S=mask^(1<<p1)^(1<<p2);
		double result=0;
		for(int sub=S;;sub=(sub-1)&S) {

			final int S1=sub|1<<p1;
			final int S2=mask^S1;

			double x=1;
			for(int i=0;i<n;++i) {
				if(i!=p1&&(S1&(1<<i))!=0) {
					x*=f1[S2][i];
				}
			}
			result+=dfs(S1)*dfs(S2)*f2[S2][p1]*x;

			if(0==sub) {
				break;
			}
		}
		visited[mask]=true;
		return dp[mask]=result;
	}
}

  

 

posted @ 2017-09-23 15:49  朝拜明天19891101  阅读(237)  评论(0编辑  收藏  举报