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

    problem1 link

    暴力枚举$r$只兔子的初始位置,然后模拟即可。

    problem2 link

    假设刚生下来的兔子是1岁,那么能够生小兔子的兔子的年龄是至少3岁。

    那么所有的兔子按照年龄可以分为1岁,2岁,大于等于3岁三种情况。不妨令个数分别为$a_{1},a_{2},a_{3}$

    在每年生完兔子后,假如是四月,这时候1岁的兔子和大于等于3岁的兔子的数量是一样的($a_{1}=a_{3}$)。那么在11月的时候,如果要去掉一半的兔子,那么一定是大于等于三岁的所有兔子和2岁兔子的一半。$a_{3}=0,a_{2}=frac{a_{2}}{2}$ or $a_{2}=frac{a_{2}+1}{2}$

    现在的问题是要确定现在2岁的兔子的个数是奇数还是偶数。不妨令三种兔子的奇偶数分别是$x_{1},x_{2},x_{3}$

    假设$x_{2}=t*2^{51}+r$,$0 leq r < 2^{51}$

    那么只需要用$r$的奇偶性来代表$x_{2}$的奇偶性即可,即便有除以2,以及加1再除以2的操作。因为$t*2^{51}$除以若干次2后(小于等于50次)仍然是偶数。

    problem3 link

    假设有$n$只兔子

    首先计算出每个兔子得分的最大值最小值。minPoints,maxPoints

    设选出的selected只兔子的最后一只的编号为$x$, 假设它此时的得分 maxPoints[x]

    另外假设其他选择的兔子都是它们的最高得分,而未选兔子都是它们的最低得分

    令$f[i][j][k]$表示在前$i$只兔子中,有$j$只的排名高于$x$且在这$j$只中选出了$k$只的情况有多少种。那此次的答案为$Answer_{x}=sum_{i= selected}^{qualified}f[n][i][selected]$

    这里需要考虑的是,会不会出现这样的情况导致少计算了方案数:由于$x$固定得了maxPoints[x]分,而如果它的得分少于maxPoints[x]时,可能会出现某个兔子$t$的排名在$x$之前。(比如$minPoints[x]<maxPoints[t]<maxPoints[x]$)

    其实这种情况不会漏算,因为当枚举$t$作为最后选出兔子的最后一只时,会算上这种情况。

    因此,只需要考虑选择的兔子都是它们的最高得分,而未选兔子都是它们的最低得分即可。

    code for problem1

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class RabbitStepping {
    
    	int result = 0;
    	String field = null;
    	int[] q = null;
    	int[] pre = null;
    
    	public double getExpected(String field, int r) {
    		this.field = field;
    		q = new int[field.length()];
    		pre = new int[field.length()];
    		dfs(0, 0, r, new int[field.length()]);
    		long p = 1;
    		for (int i = 1; i <= r; ++ i) {
    			p = p * (field.length() + 1 - i) / i;
    		}
    		return 1.0 * result / p;
    	}
    	void dfs(int dep, int start, int tot, int[] p) {
    		if (dep == tot) {
    			cal(p);
    			return;
    		}
    		if (start == p.length) {
    			return;
    		}
    		if (tot - dep > p.length - start) {
    			return;
    		}
    		for (int i = start; i < p.length; ++ i) {
    			p[i] = 1;
    			dfs(dep + 1, i + 1, tot, p);
    			p[i] = 0;
    		}
    	}
    
    	void move(int from, int to) {
    		q[to] += 1;
    		q[from] -= 1;
    		pre[to] = from;
    	}
    
    	void cal(int[] p) {
    		for (int i = 0; i < p.length; ++ i) {
    			q[i] = p[i];
    		}
    		int size = q.length;
    		Arrays.fill(pre, -1);
    		int[] pre1 = new int[p.length];
    		int[] q1 = new int[p.length];
    		while (size > 2) {
    			for (int i = 0; i < size; ++ i) {
    				pre1[i] = pre[i];
    				q1[i] = q[i];
    			}
    			for (int i = 0; i < size; ++ i) {
    				if (q1[i] == 0) {
    					continue;
    				}
    				if (i == 0) {
    					move(0, 1);
    				}
    				else if (i == size - 1 || i == size - 2) {
    					move(i, i - 1);
    				}
    				else if (field.charAt(i) == 'W'){
    					move(i, i - 1);
    				}
    				else if (field.charAt(i) == 'B') {
    					move(i, i + 1);
    				}
    				else {
    					if (size == p.length) {
    						move(i, i - 1);
    					}
    					else {
    						move(i, pre1[i]);
    					}
    				}
    			}
    			for (int i = 0; i < size; ++ i) {
    				if (q[i] >= 2) {
    					q[i] = 0;
    					pre[i] = 0;
    				}
    			}
    			size -= 1;
    		}
    		for (int i = 0; i < size; ++ i) {
    			result += q[i];
    		}
    	}
    }
    

      


    code for problem2

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class RabbitIncreasing {
    
    	final static int mod = 1000000009;
    	final static long MOD = 1l << 51;
    	final static int rev2 = Pow(2, mod - 2, mod);
    
    	public int getNumber(int[] leaving, int k) {
    		int a3 = 0, a2 = 0, a1 = 1;
    		long x3 = 0, x2 = 0, x1 = 1;
    		if (leaving[0] == 1) {
    		    return 0;
    		}
    		int t = 0;
    		for (int i = 2; i <= k; ++ i) {
    			a3 = (a3 + a2) % mod;
    			a2 = a1;
    			a1 = a3;
    			x3 = (x3 + x2) % MOD;
    			x2 = x1;
    			x1 = x3;
    			if (t < leaving.length && leaving[t] == i) {
    				x3 = 0;
    				a3 = 0;
    				if ((x2 & 1) == 1) {
    					x2 -= 1;
    					a2 = (a2 + mod - 1) % mod;
    				}
    				x2 >>= 1;
    				a2 = (int)((long)a2 * rev2 % mod);
    				t += 1;
    			}
    		}
    		return ((a3 + a2) % mod + a1) % mod;
    
    	}
    
    	static int Pow(int a, int b, int mod) {
    		int result = 1;
    		a %= mod;
    		while (b != 0) {
    			if ((b & 1) == 1) {
    				result = (int)((long)result * a % mod);
    			}
    			a = (int)((long)a * a % mod);
    			b >>= 1;
    		}
    		return result;
    	}
    
    
    }
    

      


    code for problem3

    import java.util.*;
    import java.math.*;
    import static java.lang.Math.*;
    
    public class RabbitProgramming {
    
    	int[] minPoints = null;
    	int[] maxPoints = null;
    	long[][][] f = null;
    	int n;
    	int qualified;
    	int selected;
    
    	public long getTeams(int[] points, String[] standings, int qualified, int selected) {
    		this.n = standings.length;
    		this.qualified = qualified;
    		this.selected = selected;
    		minPoints = new int[n];
    		maxPoints = new int[n];
    		for (int i = 0; i < points.length; ++ i) {
    			for (int j = 0; j < n; ++ j) {
    				if (standings[j].charAt(i) == 'N') {
    					continue;
    				}
    				if (points[i] > 0) {
    					minPoints[j] += points[i];
    					maxPoints[j] += points[i];
    				}
    				else {
    					maxPoints[j] += -points[i];
    				}
    			}
    		}
    		f = new long[n][qualified + 1][selected + 1];
    		long result = 0;
    		for (int x = 0; x < n; ++ x) {
    			cal(x);
    			for (int i = selected; i <= qualified; ++ i) {
    				result += f[n - 1][i][selected];
    			}
    		}
    		return result;
    	}
    	void cal(int x) {
    		for (int i = 0; i < n; ++ i) {
    			for (int j = 0; j <= qualified; ++ j) {
    				Arrays.fill(f[i][j], 0);
    			}
    		}
    		if (x == 0) {
    			f[0][1][1] = 1;
    		}
    		else {
    			if (minPoints[0] < maxPoints[x]) {
    				f[0][0][0] = 1;
    			}
    			else {
    				f[0][1][0] = 1;
    			}
    			if (maxPoints[0] >= maxPoints[x]) {
    				f[0][1][1] = 1;
    			}
    		}
    		for (int i = 1; i < n; ++ i) {
    			for (int j = 0; j <= qualified; ++ j) {
    				for (int k = 0; k <= selected; ++ k) {
    					final long val = f[i - 1][j][k];
    					if(val == 0) {
    						continue;
    					}
    					if (i == x) {
    						if (j < qualified && k < selected) {
    							f[i][j + 1][k + 1] += val;
    						}
    						continue;
    					}
    					if (i < x && minPoints[i] < maxPoints[x]
    							|| i > x && minPoints[i] <= maxPoints[x]) {
    						f[i][j][k] += val;
    					}
    					else if(j < qualified) {
    						f[i][j + 1][k] += val;
    					}
    					if ((i < x && maxPoints[i] >= maxPoints[x]
    							|| i > x && maxPoints[i] > maxPoints[x])
    							 && j < qualified && k <selected) {
    						f[i][j + 1][k + 1] += val;
    					}
    				}
    			}
    		}
    	}
    }
    

      

  • 相关阅读:
    调用外部 DLL 中的函数(显示调用)
    模式窗体与非模式窗体
    使用PChar和string类型时的内存分配技术
    保密卡程序的编写
    Dll 使用 PChar 参数的小例子
    delphi动态创建组件的颜色
    Dll 模式窗口与非模式窗口
    调用外部 DLL 中的函数(隐式调用)
    内核读写只读内存方法总结[Delphi描述][转帖]
    delphi资源文件制作及使用详解
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/7821194.html
Copyright © 2011-2022 走看看