problem1 link

枚举第一个数和第二个数即可确定公差。

problem2 link

设高度为$n$,宽度为$m$,且$n \ge m$

如果$m \ge 5$,那么答案为0。这个可以通过抽屉原理来说明。考虑第一行,假设$n=m=5$,那么第一行最后一定有至少3个白色或黑色,不妨设为白色。不妨单独将这3列抽出来,现在就是一个$5*3(n=5)$的矩阵。那么对于第2,3,4,5行来说,不会存在一行有两个白色。对于黑色格子来说有两种情况:

(1)存在一行有三个黑色。那么其他三行不能有两个或者三个黑色,所以只能是一个黑色,这意味有两个白色,这样就和第一行冲突了。

(2)不存在任意一行有三个黑色,因为也不能有两个白色,所以只能是一个白色两个黑色,那么有三种排列方式,黑黑白,黑白黑,白黑黑。这样的话只能满足4行,第五行无论怎么放置都会冲突。如下图所示:

所以只需要考虑$m \le 4$的情况。

假设$m=4$,假设已经放置好了第1行到第$i-1$行,那么对于第$i$行来说,只需要记录一些信息来判断第$i$行的某两列是否可以都是白色或者都是黑色即可(保证不跟上面的某一行的两列形成不合法的情况)。

这样的话只有$C_{4}^{2}=6$种情况,即:0011,0101,1001,0110,1010,1100。将它们编号为0到5.

设dp的数组为$f[n][2^{6}][2^{6}]$

所以可以用一个状态$f[i][wst][bst]$来表示前$i$行放置之后,后面每一行不能出现白色格子的状态为$wst$且黑色格子状态为$bst$的放置方案数。

problem3 link

首先,对于凸包H上任意一点p,H上距离p最远的点一定是H的某个顶点。

其次,距离凸包上p附近的一些点的最远顶点必定跟距离p的最远顶点是同一个顶点。

所以,首先需要对H的边进行一些划分,也就是划分成若干个片段,每个片段的最远点是同一个顶点。划分的方法是枚举H的任意两个顶点$a,b$,线段$ab$的垂直平分线将H分为两半,一半的点到$a$的距离最大,另一半到$b$最大。该垂直平分线与H有两个交点。将所有的这样的交点收集在一起,那么任意两个相邻的交点所划分的一定是满足上面描述的一个片段。

然后就是对每个片段依次进行计算。设片段为$s$,距离$s$的最远点为$L$,其实就是计算假设$L$有一个光源,$s$上有多长的距离被内部凸包遮挡。可以这样计算:枚举内部凸包的每个点$p$,计算由$p,L$确定的直线与线段$s$的交点,那么对于任意两个$s$上的相邻交点$p_{1},p_{2}$,如果$p_{1},p_{2}$的中点与$L$组成的线段与内部凸包有交点,那么线段$p_{1}p_{2}$被遮挡。

code for problem1

import java.util.*;
import java.math.*;
import static java.lang.Math.*; public class AfraidOfEven { final static int MAX = Integer.MAX_VALUE;
public int[] restoreProgression(int[] seq) {
final int n = seq.length;
int[] result = new int[n];
for (long a = 1; a * seq[0] <= MAX; a <<= 1) {
for (long b = 1; b * seq[1] <= MAX; b <<= 1) {
result[0] = (int)(seq[0] * a);
result[1] = (int)(seq[1] * b);
if (check(result, seq)) {
return result;
}
}
}
return result;
}
boolean check(int[] a, int[] b) {
int d = a[1] - a[0];
for (int i = 2; i < b.length; ++ i) {
long t = b[i];
while (t <= MAX && t - a[i - 1] != d) {
t <<= 1;
}
if (t > MAX) {
return false;
}
a[i] = (int)t;
}
return true;
}
}

  

code for problem2

import java.util.*;
import java.math.*;
import static java.lang.Math.*; public class RectangleAvoidingColoring { public long count(String[] board) {
if (board.length >= 5 && board[0].length() >= 5) {
return 0;
}
if (board[0].length() >= 5) {
String[] board1 = new String[board[0].length()];
for (int i = 0; i < board[0].length(); ++ i) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < board.length; ++ j) {
sb.append(board[j].charAt(i));
}
board1[i] = sb.toString();
}
return count(board1);
}
final int n = board.length;
final int m = board[0].length(); if (m == 1) {
long result = 1;
for (int i = 0; i < n; ++ i) {
if (board[i].charAt(0) == '?') {
result <<= 1;
}
}
return result;
} final int K = m * (m - 1) / 2; int[] T1 = new int[1 << m];
for (int i = 0, id = 0; i < (1 << m); ++ i) {
int num = 0;
for (int j = 0; j < m; ++ j) {
if (contains(i, 1 << j)) {
++ num;
}
}
if (num == 2) {
T1[i] = id ++;
}
} int[][] T = new int[1 << m][2];
for (int i = 0; i < (1 << m); ++ i) {
int b = 0;
int w = 0;
for (int x = 0; x < m; ++ x) {
boolean bx = contains(i, 1 << x);
for (int y = x + 1; y < m; ++ y) {
boolean by = contains(i, 1 << y);
if (bx != by) {
continue;
}
if (by) {
b |= 1 << T1[1 << x | 1 << y];
}
else {
w |= 1 << T1[1 << x | 1 << y];
}
}
}
T[i][0] = w;
T[i][1] = b;
} long[][][] f = new long[n + 1][1 << K][1 << K];
f[0][0][0] = 1;
for (int i = 1; i <= n; ++ i) {
for (int wst = 0; wst < (1 << K); ++ wst) {
for (int bst = 0; bst < (1 << K); ++ bst) {
final long val = f[i - 1][wst][bst];
if (val == 0) {
continue;
}
for (int st = 0; st < (1 << m); ++ st) {
if (check(st, board[i - 1])) {
int w = T[st][0];
int b = T[st][1];
if (contains(wst, w) || contains(bst, b)) {
continue;
}
f[i][wst | w][bst | b] += val;
}
}
}
}
}
long result = 0;
for (int wst = 0; wst < (1 << K); ++ wst) {
for (int bst = 0; bst < (1 << K); ++bst) {
result += f[n][wst][bst];
}
}
return result;
} static boolean contains(int st, int sub) {
return (st & sub) != 0;
}
static boolean check(int st, String s) {
for (int i = 0; i < s.length(); ++ i) {
int t = (st >> i) & 1;
if (t == 0 && s.charAt(i) == 'B'
|| t == 1 && s.charAt(i) == 'W') {
return false;
}
}
return true;
}
}

  

code for problem3

import java.util.*;

public class Deposit {

	static final double EPS = 1e-9;

	static boolean isZero(double x) {
return -EPS < x && x < EPS;
} static class Point {
double x;
double y; Point() {}
Point(double x, double y) {
this.x = x;
this.y = y;
} double multiply(Point p) {
return x * p.y - y * p.x;
}
Point multiply(double t) {
return new Point(x * t, y * t);
}
Point divide(double t) {
return new Point(x / t, y / t);
} Point substract(Point p) {
return new Point(x - p.x, y - p.y);
} Point add(Point p) {
return new Point(x + p.x, y + p.y);
} Point vertical() {
return new Point(-y, x);
} double length() {
return Math.sqrt(x * x + y * y);
} boolean equals(Point p) {
return isZero(x - p.x) && isZero(y - p.y);
} } static class PointComparator implements Comparator<Point> { Point start; PointComparator(Point start) {
this.start = start;
} public int compare(Point o1, Point o2) {
double d1 = o1.substract(start).length();
double d2 = o2.substract(start).length();
if (isZero(d1 - d2)) {
return 0;
}
return d1 < d2? -1 : 1;
}
} Point[] out = null;
Point[] inner = null;
int n;
int m; public double successProbability(int[] siteX, int[] siteY, int[] depositX, int[] depositY) {
n = siteX.length;
out = new Point[n];
for (int i = 0; i < n; ++ i) {
out[i] = new Point(siteX[i], siteY[i]);
}
m = depositX.length;
inner= new Point[m];
for (int i = 0; i < m; ++ i) {
inner[i] = new Point(depositX[i], depositY[i]);
}
double sum = 0;
for (int i = 0; i < n; ++ i) {
sum += out[i].substract(out[(i + 1) % n]).length();
} double validLength = 0;
for (int i = 0; i < n; ++ i) {
Point p = out[i];
Point q = out[(i + 1) % n];
validLength += calculate(p, q);
}
return validLength / sum;
} double calculate(Point start, Point end) { List<Point> allRange = new ArrayList<>();
allRange.add(start);
allRange.add(end);
for (int i = 0; i < n; ++ i) {
for (int j = i + 1; j < n; ++ j) {
Point p = out[i].add(out[j]).multiply(0.5);
Point q = p.add(out[i].substract(out[j]).vertical());
if (isParallel(start, end, p, q)) {
continue;
}
Point c = getLineCrossLine(start, end, p, q);
if (isOnSegment(c, start, end)) {
allRange.add(c);
}
}
}
Collections.sort(allRange, new PointComparator(start)); double result = 0;
for (int i = 0; i + 1 < allRange.size(); ++ i) {
Point a = allRange.get(i);
Point b = allRange.get(i + 1);
if (a.equals(b)) {
continue;
}
Point f = getFarthestPoint(a.add(b).multiply(0.5), out);
result += checkBlocked(a, b, f, inner);
}
return result;
} static boolean isBetween(double a, double L, double R) {
if (L < R) {
return L - EPS < a && a < R + EPS;
}
return R - EPS < a && a < L + EPS;
} static boolean isOnSegment(Point a, Point p, Point q) {
return isBetween(a.x, p.x, q.x) && isBetween(a.y, p.y, q.y);
} double checkBlocked(Point start, Point end, Point L, Point[] h) {
List<Point> list = new ArrayList<>();
list.add(start);
list.add(end);
for (Point hp: h) {
if (isParallel(start, end, L, hp)) {
continue;
}
Point p = getLineCrossLine(start, end, L, hp);
if (isOnSegment(p, start, end)) {
list.add(p);
}
}
Collections.sort(list, new PointComparator(start)); double result = 0;
for (int i = 0; i + 1 < list.size(); ++ i) {
Point p = list.get(i);
Point q = list.get(i + 1);
if (p.equals(q)) {
continue;
}
if (isIntersectConvex(p.add(q).multiply(0.5), L, h)) {
result += p.substract(q).length();
}
}
return result;
} static boolean isIntersectConvex(Point p, Point q, Point[] h) {
for (int i = 0; i < h.length; ++ i) {
Point a = h[i];
Point b = h[(i + 1) % h.length];
if (isParallel(a, b, p, q)) {
continue;
}
Point c = getLineCrossLine(a, b, p, q);
if (isOnSegment(c, p, q) && isOnSegment(c, a, b)) {
return true;
}
}
return false;
} static boolean isParallel(Point a, Point b, Point p, Point q) {
return isZero(a.substract(b).multiply(p.substract(q)));
} static Point getFarthestPoint(Point p, Point[] h) {
int id = 0;
double dmax = 0;
for (int i = 0; i < h.length; ++ i) {
Point q = h[i];
double d = p.substract(q).length();
if (d > dmax) {
id = i;
dmax = d;
}
}
return h[id];
} static Point getLineCrossLine(Point a, Point b, Point p, Point q) {
double s1 = p.substract(a).multiply(q.substract(a));
double s2 = q.substract(b).multiply(p.substract(b));
return a.multiply(s2).add(b.multiply(s1)).divide(s1 + s2);
}
}

  

topcoder srm 485 div1的更多相关文章

  1. Topcoder SRM 643 Div1 250<peter_pan>

    Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...

  2. Topcoder Srm 726 Div1 Hard

    Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...

  3. topcoder srm 714 div1

    problem1 link 倒着想.每次添加一个右括号再添加一个左括号,直到还原.那么每次的右括号的选择范围为当前左括号后面的右括号减去后面已经使用的右括号. problem2 link 令$h(x) ...

  4. topcoder srm 738 div1 FindThePerfectTriangle(枚举)

    Problem Statement      You are given the ints perimeter and area. Your task is to find a triangle wi ...

  5. Topcoder SRM 602 div1题解

    打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...

  6. Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串

    Problem Statement      The Happy Letter game is played as follows: At the beginning, several players ...

  7. Topcoder SRM 584 DIV1 600

    思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...

  8. TopCoder SRM 605 DIV1

    604的题解还没有写出来呢.先上605的. 代码去practice房间找. 说思路. A: 贪心,对于每个类型的正值求和,如果没有正值就取最大值,按着求出的值排序,枚举选多少个类型. B: 很明显是d ...

  9. topcoder srm 575 div1

    problem1 link 如果$k$是先手必胜那么$f(k)=1$否则$f(k)=0$ 通过对前面小的数字的计算可以发现:(1)$f(2k+1)=0$,(2)$f(2^{2k+1})=0$,(3)其 ...

随机推荐

  1. mint-ui Picker的使用

    <template> <div v-bind:style="{minHeight:clientHeight + 'px'}" id="recive-mi ...

  2. Nginx配置文件具体配置解释

    Nginx配置文件具体配置解释   #定义Nginx运行的用户和用户组 user www www; #nginx进程数,建议设置为等于CPU总核心数. worker_processes 8; #全局错 ...

  3. ling join 报错The specified LINQ expression contains references to queries that are associated with different cont

    The specified LINQ expression contains references to queries that are associated with different cont ...

  4. Yii数据对象笔记

    要执行一个SQL查询,应该遵循以下步骤 - 创建一个 yii\db\Command 的 SQL查询命令 绑定参数(非必须) 执行命令 第1步 - 创建一个 actionTestDb()方法在 Site ...

  5. Java基础语法(三)

    七.方法 定义: 方法就是完成特定功能的代码块 在很多语言里面都有函数的定义 函数在Java中被称为方法 格式: 修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2…) { 函数体; ...

  6. 使用Python中的config配置

    Python中有ConfigParser类,可以很方便的从配置文件中读取数据(如DB的配置,路径的配置),所以可以自己写一个函数,实现读取config配置. config文件的写法比较简单,[sect ...

  7. 创建 .m2 文件夹

    首次使用 Maven 创建 .m2 文件夹 1. cmd2. mvn help:system

  8. kali 开启ssh服务

    1.    一.配置SSH参数 修改sshd_config文件,命令为: vi /etc/ssh/sshd_config 将#PasswordAuthentication no的注释去掉,并且将NO修 ...

  9. 转:【专题四】自定义Web浏览器

    前言: 前一个专题介绍了自定义的Web服务器,然而向Web服务器发出请求的正是本专题要介绍的Web浏览器,本专题通过简单自定义一个Web浏览器来简单介绍浏览器的工作原理,以及帮助一些初学者揭开浏览器这 ...

  10. Linux查看磁盘空间大小命令

    Linux查看磁盘空间大小命令df -hldf -hl 查看磁盘剩余空间df -h 查看每个根路径的分区大小du -sh [目录名] 返回该目录的大小du -sm [文件夹] 返回该文件夹总M数du ...