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. 笔记 : 将本地项目上传到GitHub

    一.准备工作 1. 注册github账号https://github.com, 安装git工具 https://git-for-windows.github.io/ 2. 创建SSH KEY(由于本地 ...

  2. JS实例5

    做这么一个效果  鼠标单击某个名字后变色,没选中的鼠标移动上去变色 首先布局这个效果,然后给每个表格添加单击事件onclick.鼠标放上事件onmousemove.鼠标移出事件onmouseout 容 ...

  3. Spark学习之路 (二十七)图简介

    一.图 1.1 基本概念 图是由顶点集合(vertex)及顶点间的关系集合(边edge)组成的一种数据结构. 这里的图并非指代数中的图.图可以对事物以及事物之间的关系建模,图可以用来表示自然发生的连接 ...

  4. hashcat 中文文档

    hashcat   描述 hashcat是世界上最快,最先进的密码恢复工具. 此版本结合了以前基于CPU的hashcat(现在称为hashcat-legacy)和基于GPU的oclHashcat. H ...

  5. Ontology Relations

    Overview The following page documents the relations used in the filtered GO ontology. For informatio ...

  6. Java并发编程:volatile关键字解析-转

    Java并发编程:volatile关键字解析 转自海子:https://www.cnblogs.com/dayanjing/p/9954562.html volatile这个关键字可能很多朋友都听说过 ...

  7. golang学习笔记18 用go语言编写移动端sdk和app开发gomobile

    golang学习笔记18 用go语言编写移动端sdk和app开发gomobile gomobile的使用-用go语言编写移动端sdk和app开发https://blog.csdn.net/u01249 ...

  8. pyspider操作千万级库,pyspider在对接量级较大库的策略

    pyspider操作千万级库,pyspider在对接量级较大库的策略 如果是需要pyspider正常的流程去执行,那必然是会在on_strat()时任务执行超时,可能只读取出几万条或十几万条数据就会被 ...

  9. 计蒜客--移除数组中的重复元素 (set)

    给定一个升序排列的数组,去掉重复的数,并输出新的数组的长度. 例如:数组 A = \{1, 1, 2\}A={1,1,2},你的程序应该输出 22 即新数组的长度,新数组为 \{1, 2\}{1,2} ...

  10. Linux账号管理

    Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统. 用户的账号一方面可以帮助系统管理员对使用系统的用户进行 ...