zoukankan      html  css  js  c++  java
  • topcoder srm 340 div1

    problem1 link 

    $f[i][L][R]$表示计算到第$i$个,最小最大值是$L,R$时的最少个数。

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class ProblemsToSolve {
    
    
    	int[] unique(int[] p) {
    		int n=p.length;
    		int[] a=new int[n];
    		for(int i=0;i<n;++i) {
    			a[i]=p[i];
    		}
    		Arrays.sort(a);
    		int id=0;
    		for(int i=1;i<n;++i) {
    			if(a[i]!=a[id]) {
    				a[++id]=a[i];
    			}
    		}
    		++id;
    		if(id==n) {
    			return a;
    		}
    		int[] q=new int[id];
    		for(int i=0;i<id;++i) {
    			q[i]=a[i];
    		}
    		return q;
    	}
    
    	int getindex(int[] p,int x) {
    		for(int i=0;i<p.length;++i) {
    			if(p[i]==x) {
    				return i;
    			}
    		}
    		return -1;
    	}
    
    	public int minNumber(int[] p,int variety) {
    		final int n=p.length;
    		final int[] a=unique(p);
    		final int m=a.length;
    		int[][][] f=new int[n][m][m];
    
    		for(int i=0;i<n;++i) {
    			p[i]=getindex(a,p[i]);
    		}
    
    		int result=n;
    		for(int i=0;i<n;++i) {
    			for(int j=0;j<m;++j) {
    				for(int k=0;k<m;++k) {
    					f[i][j][k]=-1;
    				}
    			}
    		}
    		f[0][p[0]][p[0]]=1;
    		for(int i=1;i<n;++i) {
    			for(int j=i-1;j>=i-2&&j>=0;--j) {
    				for(int x=0;x<m;++x) {
    					for(int y=x;y<m;++y) {
    						if(f[j][x][y]==-1) continue;
    
    						if(p[i]>y) {
    							if(a[p[i]]-a[x]>=variety) {
    								result=Math.min(result,f[j][x][y]+1);
    								continue;
    							}
    						}
    						else if(p[i]<x) {
    							if(a[y]-a[p[i]]>=variety) {
    								result=Math.min(result,f[j][x][y]+1);
    								continue;
    							}
    						}
    
    						final int nx=Math.min(x,p[i]);
    						final int ny=Math.max(y,p[i]);
    
    						if(f[i][nx][ny]==-1||f[i][nx][ny]>f[j][x][y]+1) {
    							f[i][nx][ny]=f[j][x][y]+1;
    						}
    
    					}
    				}
    			}
    		}
    		return result;
    	}
    }

    problem2 link

    $f[i][j]$表示两个分数分别达到$i,j$时选择的最少课程数,并记录选择的课程是哪些。这样进行bfs即可。

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class CsCourses {
    
    
    	String int2string(int x) {
    		if(x<10) {
    			return "0"+Integer.toString(x);
    		}
    		return Integer.toString(x);
    	}
    
    	public int[] getOrder(int[] t, int[] p, int[] e, int skillBound) {
    		if(skillBound==0) {
    			return new int[0];
    		}
    		final int n=t.length;
    
    		int[][] f=new int[51][51];
    		String[][] d=new String[51][];
    		boolean[][] inq=new boolean[51][51];
    		for(int i=0;i<51;++i) {
    			d[i]=new String[51];
    			for(int j=0;j<51;++j) {
    				f[i][j]=-1;
    				inq[i][j]=false;
    			}
    		}
    
    		Queue<Integer> que=new LinkedList<>();
    
    
    		for(int i=0;i<n;++i) {
    			if(t[i]<=1&&p[i]<=1&&e[i]>=1&&t[i]+p[i]>0&&f[t[i]][p[i]]==-1) {
    				f[t[i]][p[i]]=1;
    				d[t[i]][p[i]]=int2string(i);
    				que.offer(t[i]*100+p[i]);
    				inq[t[i]][p[i]]=true;
    			}
    		}
    
    
    		while(!que.isEmpty()) {
    			final int ii=que.peek()/100;
    			final int jj=que.peek()%100;
    			que.poll();
    			if(ii>=skillBound&&jj>=skillBound) {
    				continue;
    			}
    
    			for(int k=0;k<n;++k) {
    				if(t[k]<=ii&&p[k]<=jj) continue;
    				if(t[k]-ii>1) continue;
    				if(p[k]-jj>1) continue;
    				if(e[k]<=f[ii][jj]) continue;
    				final int nii=Math.max(ii,t[k]);
    				final int njj=Math.max(jj,p[k]);
    
    				if(f[nii][njj]==-1
    						||f[nii][njj]>f[ii][jj]+1
    						||f[nii][njj]==f[ii][jj]+1
    						&&0<d[nii][njj].compareTo(d[ii][jj]+","+int2string(k))) {
    					f[nii][njj]=f[ii][jj]+1;
    					d[nii][njj]=d[ii][jj]+","+int2string(k);
    					if(!inq[nii][njj]) {
    						que.offer(nii*100+njj);
    						inq[nii][njj]=true;
    					}
    				}
    
    			}
    		}
    		int num=Integer.MAX_VALUE;
    		String route="";
    		for(int i=skillBound;i<51;++i) {
    			for(int j=skillBound;j<51;++j) {
    				if(f[i][j]!=-1&&f[i][j]<num||f[i][j]==num&&d[i][j].compareTo(route)<0) {
    					num=f[i][j];
    					route=d[i][j];
    				}
    			}
    		}
    		if(num==Integer.MAX_VALUE) {
    			return new int[0];
    		}
    		String[] path=route.split(",");
    		int[] result=new int[path.length];
    
    		for(int i=0;i<path.length;++i) {
    			result[i]=Integer.valueOf(path[i]);
    		}
    		return result;
    
    	}
    }

    problem3 link

    判断一个点在多边形的内部还是外部可以用射线法。一条从某一点发出的射线与多边形有奇数个交点则在内部。

    初始时认为每个格子有个垂直向上的射线。每次横着走时,下面的所有格子与多边形的交点个数增加了1.

    $f[x][y][mask]$表示从$(0,0)$走到$(x,y)$,经过的$'I'$或者$'X'$的状态是$mask$的最短路。

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class VegetableGarden {
    	
    	public int[] getMinDistances(String[] g) {
    		final int n = g.length;
    		final int m = g[0].length();
    		int id = 0;
    		int badMask=0;
    		int iNum=0;
    		List<Integer> list=new ArrayList<>();
    		for(int i=0;i<n;++i) {
    			for(int j=0;j<m;++j) {
    				if(g[i].charAt(j)!='.') {
    					if(g[i].charAt(j)=='X') {
    						badMask|=1<<id;
    					}
    					else {
    						++iNum;
    					}
    					list.add(i*100+j);
    					++id;
    				}
    			}
    		}
    		int[][][] f=new int[n+1][m+1][1<<id];
    		boolean[][][] inq=new boolean[n+1][m+1][1<<id];
    		for(int i=0;i<n+1;++i) {
    			for(int j=0;j<m+1;++j) {
    				for(int k=0;k<(1<<id);++k) {
    					f[i][j][k]=-1;
    					inq[i][j][k]=false;
    				}
    			}
    		}
    		Queue<Integer> queue=new LinkedList<>();
    		f[0][0][0]=0;
    		inq[0][0][0]=true;
    		queue.offer(0);
    		final int[] dx={0,1,0,-1};
    		final int[] dy={1,0,-1,0};
    		while(!queue.isEmpty()) {
    			final int mask=queue.peek()/10000;
    			final int x=queue.peek()%10000/100;
    			final int y=queue.peek()%100;
    			queue.poll();
    			inq[x][y][mask]=false;
    			for(int d=0;d<4;++d) {
    				final int xx=x+dx[d];
    				final int yy=y+dy[d];
    				if(xx<0||yy<0||xx>=n+1||yy>=m+1) continue;
    				int nMask=mask;
    				if(d==0||d==2) {
    					final int column=d==0?y:y-1;
    
    					for(int k=0;k<list.size();++k) {
    						final int nx=list.get(k)/100;
    						final int ny=list.get(k)%100;
    						if(ny==column&&nx>=x) {
    							nMask^=1<<k;
    						}
    					}
    				}
    
    				if(f[xx][yy][nMask]==-1||f[xx][yy][nMask]>f[x][y][mask]+1) {
    					f[xx][yy][nMask]=f[x][y][mask]+1;
    					if(!inq[xx][yy][nMask]) {
    						inq[xx][yy][nMask]=true;
    						queue.offer(nMask*10000+xx*100+yy);
    					}
    				}
    
    			}
    		}
    		int[] result=new int[iNum];
    		for(int i=0;i<(1<<id);++i) {
    			if((i&badMask)!=0) continue;
    			if(f[0][0][i]==-1) continue;
    			int c=0;
    			int k=i;
    			while(k!=0) {
    				c+=k&1;
    				k>>=1;
    			}
    			if(c==0) {
    				continue;
    			}
    			if(result[c-1]==0||result[c-1]>f[0][0][i]) {
    				result[c-1]=f[0][0][i];
    			}
    		}
    		return result;
    	}
    }
    

      

  • 相关阅读:
    Quartz2D复习(三) --- 涂鸦
    Quartz2D复习(二) --- 手势解锁
    Quartz2D复习(一)--- 基础知识 / 绘制线段圆弧 / 图片水印 / 截图
    控制器和应用数据存储
    UIApplication
    setTimeout和setInterval
    工作中碰到的js问题(disabled表单元素不能提交到服务器)
    通知
    UITableViewController和延时执行、自定义控件
    将博客搬至CSDN
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/7407120.html
Copyright © 2011-2022 走看看