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
这个可以用数学归纳法证明
problem2 link
假设字符串的总长度为$n$
首先,设$x_{k}$为位置$i$经过$k$ 次交换后仍然在$i$的概率,那么在其他位置$j(j\ne i)$的概率为$\frac{x}{n-1}$.可以得到关于$x_{k}$的转移方程$x_{0}=1, x_{k}=x_{k-1}*\frac{C_{n-1}^{2}}{C_{n}^{2}}+(1-x_{k-1})*\frac{1}{C_{n}^{2}}$
计算出了$x_{k}$之后。对于$[1,n]$的某个位置$i$,其对答案的贡献为$G(i)=(x_{k}*P+\frac{x_{k}}{n-1}*(T-P))*S_{i}$
其中$S_{i}$表示位置$i$的数字。$P$表示任意选一个区间包含$i$的概率,$P=F_{i}=\frac{2i(n-i+1)}{n(n+1)}$,而$T=\sum_{i=1}^{n}F_{i}$
problem3 link
这个可以用最大流来解决。
(1)将每个黑色的格子拆分成两个点,一个表示进入该格子,一个表示离开该格子。这两个点之间连边,流量为1。
(2)将所有白色的格子,分为两类,第一类是列数为偶数的,第二类是列数为奇数的。源点向第一类连边,流量为1;第二类向汇点连边,流量为1。另外,第一类向周围的四个黑色格子拆成的第一个连边,黑色格子拆成的第二个向第二类连边。
最后求最大流即可。
code for problem1
#include <string> class TheNumberGameDivOne {
public:
std::string find(long long n) {
if (IsFirstWin(n)) {
return "John";
}
return "Brus";
} private:
bool IsFirstWin(long long n) {
if (n == 1 || n % 2 == 1) {
return false;
}
int c = 0;
while (n % 2 == 0) {
++c;
n /= 2;
}
if (n == 1 && c % 2 == 1) {
return false;
}
return true;
}
};
code for problem2
#include <string>
#include <vector> class TheSwapsDivOne {
public:
double find(const std::vector<std::string> &seq, int k) {
int n = 0;
int sum = 0;
for (const auto &e : seq) {
n += static_cast<int>(e.size());
for (char c : e) {
sum += c - '0';
}
}
auto Get = [&](int t) { return 2.0 * t * (n - t + 1) / n / (n + 1); };
double sum_rate = 0.0;
for (int i = 1; i <= n; ++i) {
sum_rate += Get(i);
}
double p = 1.0 * (n - 2) / n;
double q = 2.0 / n / (n - 1);
double x = 1.0;
for (int i = 1; i <= k; ++i) {
x = p * x + q * (1 - x);
}
double result = 0;
int idx = 0;
for (const auto &e : seq) {
for (size_t i = 0; i < e.size(); ++i) {
++idx;
int d = e[i] - '0';
double r = Get(idx);
result += (x * r + (1 - x) / (n - 1) * (sum_rate - r)) * d;
}
}
return result;
}
};
code for problem3
#include <limits>
#include <string>
#include <unordered_map>
#include <vector> template <typename FlowType>
class MaxFlowSolver {
static constexpr FlowType kMaxFlow = std::numeric_limits<FlowType>::max();
static constexpr FlowType kZeroFlow = static_cast<FlowType>(0);
struct node {
int v;
int next;
FlowType cap;
}; public:
int VertexNumber() const { return used_index_; } FlowType MaxFlow(int source, int sink) {
source = GetIndex(source);
sink = GetIndex(sink); int n = VertexNumber();
std::vector<int> pre(n);
std::vector<int> cur(n);
std::vector<int> num(n);
std::vector<int> h(n);
for (int i = 0; i < n; ++i) {
cur[i] = head_[i];
num[i] = 0;
h[i] = 0;
}
int u = source;
FlowType result = 0;
while (h[u] < n) {
if (u == sink) {
FlowType min_cap = kMaxFlow;
int v = -1;
for (int i = source; i != sink; i = edges_[cur[i]].v) {
int k = cur[i];
if (edges_[k].cap < min_cap) {
min_cap = edges_[k].cap;
v = i;
}
}
result += min_cap;
u = v;
for (int i = source; i != sink; i = edges_[cur[i]].v) {
int k = cur[i];
edges_[k].cap -= min_cap;
edges_[k ^ 1].cap += min_cap;
}
}
int index = -1;
for (int i = cur[u]; i != -1; i = edges_[i].next) {
if (edges_[i].cap > 0 && h[u] == h[edges_[i].v] + 1) {
index = i;
break;
}
}
if (index != -1) {
cur[u] = index;
pre[edges_[index].v] = u;
u = edges_[index].v;
} else {
if (--num[h[u]] == 0) {
break;
}
int k = n;
cur[u] = head_[u];
for (int i = head_[u]; i != -1; i = edges_[i].next) {
if (edges_[i].cap > 0 && h[edges_[i].v] < k) {
k = h[edges_[i].v];
}
}
if (k + 1 < n) {
num[k + 1] += 1;
}
h[u] = k + 1;
if (u != source) {
u = pre[u];
}
}
}
return result;
} MaxFlowSolver() = default; void Clear() {
edges_.clear();
head_.clear();
vertex_indexer_.clear();
used_index_ = 0;
} void InsertEdge(int from, int to, FlowType cap) {
from = GetIndex(from);
to = GetIndex(to);
AddEdge(from, to, cap);
AddEdge(to, from, kZeroFlow);
} private:
int GetIndex(int idx) {
auto iter = vertex_indexer_.find(idx);
if (iter != vertex_indexer_.end()) {
return iter->second;
}
int map_idx = used_index_++;
head_.push_back(-1);
return vertex_indexer_[idx] = map_idx;
} void AddEdge(int from, int to, FlowType cap) {
node p;
p.v = to;
p.cap = cap;
p.next = head_[from];
head_[from] = static_cast<int>(edges_.size());
edges_.emplace_back(p);
} std::vector<node> edges_;
std::vector<int> head_; std::unordered_map<int, int> vertex_indexer_;
int used_index_ = 0;
}; class TheTilesDivOne {
public:
int find(const std::vector<std::string> &board) {
MaxFlowSolver<int> solver;
int n = static_cast<int>(board.size());
int m = static_cast<int>(board[0].size());
auto GetWhite = [&](int x, int y) { return x * m + y; };
auto GetBlackIn = [&](int x, int y) { return GetWhite(x, y); };
auto GetBlackOut = [&](int x, int y) { return GetWhite(x, y) + n * m; };
auto Valid = [&](int x, int y) {
return 0 <= x && x < n && 0 <= y && y < m && board[x][y] != 'X';
};
int source = -1;
int sink = -2;
const int kDirX[] = {-1, 0, 1, 0};
const int kDirY[] = {0, 1, 0, -1};
for (int i = 0; i < n; ++i) {
for (int j = i & 1; j < m; j += 2) {
if (Valid(i, j)) {
int in = GetBlackIn(i, j);
int out = GetBlackOut(i, j);
solver.InsertEdge(in, out, 1);
for (int k = 0; k < 4; ++k) {
int kx = i + kDirX[k];
int ky = j + kDirY[k];
if (Valid(kx, ky)) {
if (kx % 2 == 0) {
solver.InsertEdge(GetWhite(kx, ky), in, 1);
} else {
solver.InsertEdge(out, GetWhite(kx, ky), 1);
}
}
}
}
}
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if ((i + j) % 2 == 1 && Valid(i, j)) {
if (i % 2 == 0) {
solver.InsertEdge(source, GetWhite(i, j), 1);
} else {
solver.InsertEdge(GetWhite(i, j), sink, 1);
}
}
}
}
return solver.MaxFlow(source, sink);
}
};
topcoder srm 575 div1的更多相关文章
- Topcoder SRM 643 Div1 250<peter_pan>
Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...
- Topcoder Srm 726 Div1 Hard
Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...
- topcoder srm 714 div1
problem1 link 倒着想.每次添加一个右括号再添加一个左括号,直到还原.那么每次的右括号的选择范围为当前左括号后面的右括号减去后面已经使用的右括号. problem2 link 令$h(x) ...
- topcoder srm 738 div1 FindThePerfectTriangle(枚举)
Problem Statement You are given the ints perimeter and area. Your task is to find a triangle wi ...
- Topcoder SRM 602 div1题解
打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...
- Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串
Problem Statement The Happy Letter game is played as follows: At the beginning, several players ...
- Topcoder SRM 584 DIV1 600
思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...
- TopCoder SRM 605 DIV1
604的题解还没有写出来呢.先上605的. 代码去practice房间找. 说思路. A: 贪心,对于每个类型的正值求和,如果没有正值就取最大值,按着求出的值排序,枚举选多少个类型. B: 很明显是d ...
- topcoder srm 640 div1
problem1 link 首先使用两个端点颜色不同的边进行连通.答案是$n-1-m$.其中$m$是联通分量的个数. problem2 link 首先构造一个最小割的模型.左边的$n_{1}$个点与源 ...
随机推荐
- Nginx的upstream反向代理、负载均衡详解
这篇文章的前提是已经配置好了NGINX,而且tomcat已经配置好了,而且能能够访问了. 说反向代理之前,我们先看看正向代理,正向代理也是大家最常接触的到的代理模式. 正向代理最大的特点是客户端非常明 ...
- Confluence实现附件下载权限的控制
背景: 公司为了方便的管理过程文档,搭建了一个Confluence服务器,版本6.9.在使用过程中,需要按照用户对空间中上传的附件进行下载权限控制. 解决过程及处理方案: 一.Confluence中导 ...
- C#进度条简单应用
进度条表示文件复制的进度: 1.将进度条最大值设置为需要复制的文件总数 2.遍历文件时每复制一个文件之后,进度条+1 ;//文件总数 progressBar1.Value = progressBar1 ...
- go 语言图片像素点处理
将一张图片色彩反转,就是将 rgb 值,分别被 255 减 package main import ( "bytes" "fmt" "image&q ...
- .net EF之CodeFirst代码先行(转)
为了支持以设计为中心的开发流程,EF还更多地支持以代码为中心 (code-centric) ,我们称为代码优先的开发,代码优先的开发支持更加优美的开发流程,它允许你在不使用设计器或者定义一个 XML ...
- VUE2 项目 引入 leaflet.draw全过程
leaflet.draw的参考文档:http://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html 这个网址不稳定,多刷新几 ...
- 蓝桥杯近3年初赛题之三(17年b组)
1. 标题: 购物单 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促销又来了!老板夫人开出了长长的购物单,都是 ...
- 排序之冒泡排序(bubblesort)
package com.pailian; /* * 冒泡排序 * 比较相邻的俩位数,这样每轮比较都会出现一个最大值或最小值 * 下一轮比较就会减少一次(因为已经知道了一个最大值或最小值) * 注意根据 ...
- Java -- 基于JDK1.8的ArrayList源码分析
1,前言 很久没有写博客了,很想念大家,18年都快过完了,才开始写第一篇,争取后面每周写点,权当是记录,因为最近在看JDK的Collection,而且ArrayList源码这一块也经常被面试官问道,所 ...
- sqlserver 导入excel
安装完office2013和sqlserver2017时,不知道是盗版问题还是啥 原因, 在sqlserver导入excel时,报错. 在把Excel导入SQL server时出现“未在本地计算机上注 ...