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

    problem1 link

    直接模拟即可。

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class Dating {
    
    	static boolean sametype(char c1,char c2) {
    		return 'a'<=c1&&c1<='z'&&'a'<=c2&&c2<='z'
    				||'A'<=c1&&c1<='Z'&&'A'<=c2&&c2<='Z';
    	}
    	
    	public String dates(String circle, int k) {
    		StringBuilder builder=new StringBuilder();
    		int startIndex=0;
    		while(true) {
    			boolean lower=false;
    			boolean upper=false;
    			for(int i=0;i<circle.length();++i) {
    				char c=circle.charAt(i);
    				if('a'<=c&&c<='z') {
    					lower=true;
    				}
    				else {
    					upper=true;
    				}
    				if(lower&&upper) {
    					break;
    				}
    			}
    			if(!lower||!upper) {
    				break;
    			}
    			for(int i=0;i<k-1;++i) {
    				++startIndex;
    				if(startIndex==circle.length()) {
    					startIndex=0;
    				}
    			}
    			int chooseIndex=-1;
    			for(int i=0;i<circle.length();++i) {
    				if(i==startIndex) {
    					continue;
    				}
    				char c1=circle.charAt(i);
    				char c2=circle.charAt(startIndex);
    				if(!sametype(c1,c2)) {
    					if(chooseIndex==-1||circle.charAt(chooseIndex)>c1) {
    						chooseIndex=i;
    					}
    				}
    			}
    			if(builder.length()>0) {
    				builder.append(" ");
    			}
    			builder.append(circle.charAt(startIndex)).append(circle.charAt(chooseIndex));
    			if(chooseIndex<startIndex) {
    				circle=circle.substring(0,chooseIndex)+
    						circle.substring(chooseIndex+1,startIndex)+
    						circle.substring(startIndex+1);
    				startIndex-=1;
    				if(startIndex==circle.length()) {
    					startIndex=0;
    				}
    			}
    			else {
    				circle=circle.substring(0,startIndex)+
    						circle.substring(startIndex+1,chooseIndex)+
    						circle.substring(chooseIndex+1);
    				if(startIndex==circle.length()) {
    					startIndex=0;
    				}
    			}
    		}
    		return builder.toString();
    	}
    }

    problem2 link

    设$h(x)$表示$[1,x]$范围内有多少符合要求的数字,那么题意就是计算$h(high)-h(low-1)$。

    对于$h(n)$来说,设$n$有$d$位数字,$f(x)(y)(z)$表示已经考虑的数字的高$x$位,$y$表示已经考虑的数字中跟$n$的高$x$位相等还是小于还是已经考虑的高$x$位都是0,三种情况;$y$表示前一位数字是多少。

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class JumpyNum {
    
    	int[][][] f=null;
    	int[] digit=null;
    
    	int dfs(int d,int tag,int pre) {
    		if(d<0) {
    			return tag==2?0:1;
    		}
    		if(f[d][tag][pre]!=-1) {
    			return f[d][tag][pre];
    		}
    		int result=0;
    		for(int i=0;i<10;++i) {
    			if(tag==0) {
    				if(Math.abs(i-pre)>=2) {
    					result+=dfs(d-1,0,i);
    				}
    			}
    			else if(tag==1) {
    				if(i<=digit[d]&&Math.abs(i-pre)>=2) {
    					result+=dfs(d-1,i==digit[d]?1:0,i);
    				}
    			}
    			else {
    				result+=dfs(d-1,i==0?2:0,i);
    			}
    		}
    		return f[d][tag][pre]=result;
    	}
    
    	int cal(int n) {
    		if(n<10) {
    			return n;
    		}
    		int d=String.valueOf(n).length();
    		digit=new int[d];
    		for(int i=0;i<d;++i) {
    			digit[i]=n%10;
    			n/=10;
    		}
    		f=new int[d][3][10];
    		for(int i=0;i<d;++i) {
    			for(int j=0;j<3;++j) {
    				for(int k=0;k<10;++k) {
    					f[i][j][k]=-1;
    				}
    			}
    		}
    		int result=0;
    		for(int i=0;i<=digit[d-1];++i) {
    			if(i==0) {
    				result+=dfs(d-2,2,0);
    			}
    			else {
    				result+=dfs(d-2,i==digit[d-1]?1:0,i);
    			}
    		}
    		return result;
    	}
    	
    	public int howMany(int low, int high) {
    		return cal(high)-cal(low-1);
    	}
    }
    

     

    problem3 link

    首先求出与$x$轴的所有交点,然后每两个相邻交点的中间的范围都有可能被绕过若干圈(如果它不在外部或者边上)。这时可以取中间值进行计算。

    对于某个点,将其与每条边的两个端点连线,计算转过的角度即可。如果在外部,那么转过的总角度是0,在内部一定是$2pi$的若干倍。

    对于两个向量$vec{a},vec{b}$,可以用$arctan(t)$来计算转角,其中$t=frac{cross(vec{a},vec{b})}{dot(vec{a},vec{b})}$。因为$frac{dot(vec{a},vec{b})}{|vec{a}|}$表示$vec{b}$在$vec{a}$上的投影长度,$frac{cross(vec{a},vec{b})}{|vec{a}|}$表示以$vec{a},vec{b}$为边的平行四边形的高(面积除以底边长),所以它们的比值就是转角的正切值。

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    
    class point
    {
    	public double x;
    	public double y;
    
    	public point(){}
    	public point(double x,double y) {
    		this.x=x;
    		this.y=y;
    	}
    
    	public double crossMultiply(point a)
    	{
    		return x*a.y-y*a.x;
    	}
    
    	public point substract(point a)
    	{
    		return new point(x-a.x,y-a.y);
    	}
    
    	public double dotMultiply(point a)
    	{
    		return x*a.x+y*a.y;
    	}
    
    	public double calculateAngle(point a)
    	{
    		return Math.atan2(crossMultiply(a),dotMultiply(a));
    	}
    
    	public void print()
    	{
    		System.out.println("x="+x+", y="+y);
    	}
    };
    
    public class AllWoundUp {
    
    	static int cal(double t,int[] px,int[] py) {
    		double sum=0;
    		final int n=px.length;
    		for(int i=0;i<n;++i) {
    			int x0=px[i],y0=py[i];
    			int x1=px[(i+1) % n],y1=py[(i+1)%n];
    			if(y0==y1&&y0==0) {
    				continue;
    			}
    			sum+=new point(x0-t,y0).calculateAngle(new point(x1-t,y1));
    		}
    		return (int)(sum/2/Math.PI+0.5);
    
    	}
    	
    	public int maxWind(int[] x, int[] y) {
    
    
    
    		List<Double> list=new ArrayList<>();
    		final int n=x.length;
    		for(int i=0;i<n;++i) {
    			int x0=x[i],y0=y[i];
    			int x1=x[(i+1)%n],y1=y[(i+1)%n];
    			if(y0==y1) {
    				continue;
    			}
    			if(x0==x1) {
    				if(y0*y1<=0) {
    					list.add((double)x0);
    				}
    				continue;
    			}
    			if(y0*y1>0) {
    				continue;
    			}
    			double k=1.0*(y0-y1)/(x0-x1);
    			list.add(-y0/k+x0);
    		}
    		Collections.sort(list);
    		int result=0;
    		for(int i=1;i<list.size();++i) {
    			if(Math.abs(list.get(i)-list.get(i-1))<1e-10) {
    				continue;
    			}
    			double t=(list.get(i)+list.get(i-1))/2;
    			boolean tag=false;
    			for(int j=0;j<n;++j) {
    				int x0=x[j],y0=y[j];
    				int x1=x[(j+1)%n],y1=y[(j+1)%n];
    				if(y0==y1&&y0==0&&Math.min(x0,x1)<=t&&t<=Math.max(x0,x1)) {
    					tag=true;
    					break;
    				}
    			}
    			if(tag) {
    				continue;
    			}
    			result=Math.max(result,cal(t,x,y));
    		}
    		return result;
    	}
    }
    

      

  • 相关阅读:
    Nginx服务器中配置非80端口的端口转发方法详解
    索引的优缺点
    redis cluster搭建
    linux 无需主机密码传输文件
    linux buffer/cache手动释放
    常用的Percona-Toolkit工具
    mysql 存储过程批量删除表
    redis(方法通用)开机自启动
    mysql 查看表的分区信息
    redis 内存分析
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/7353671.html
Copyright © 2011-2022 走看看