problem1 link

假设第$i$种出现的次数为$n_{i}$,总个数为$m$,那么排列数为$T=\frac{m!}{\prod_{i=1}^{26}(n_{i}!)}$

然后计算回文的个数,只需要考虑前一半,得到个数为$R$,那么答案为$\frac{R}{T}$.

为了防止数字太大导致越界,可以分解为质因子的表示方法。

problem2 link

假设终点所在的位置为$(tx,ty)$,那么所有底面是$1x1$的格子$(x,y)$一定满足$(x-tx)mod(3)=0,(y-ty)mod(3)=0$

把每个这样的点拆成两个点然后建立最小割的图。

源点与所有的$b$相连,终点与汇点相连,流量为无穷,割边不会在这里产生。

如果不是洞,那么这个格子拆成的两个点流量为1,表示将这个格子设为洞。

每个格子向周围连边,流量为将中间的两个格子设为洞的代价。

最后最小割就是答案。

problem3 link

首先考虑集合之间的关系。设$f[i][j]$表示前$i$个人分成$j$个集合的方案数。初始化$f[1][1]=n$。那么有:

(1)$f[i+1][j+1]=f[i][j]*j$表示新加一个集合,可以在任意两个集合之间

(2)$f[i+1][j]=f[i][j]*j*2$表示新加的元素与之前的某一个集合在一起,可以放在那个集合的前后,所以有$j*2$种方法

(3)$f[i+1][j-1]=f[i][j]*j$表示合并两个集合,可以在任意两个集合之间插入从而进行合并

最后就是对于$f[x][y]$来说,有多少种方式可以在$n$个位置上放置$x$个使得有$y$个集合并且任意两个集合不相邻。令$m=n-(x-y)$,那么相当于在$m$个位置中放置$y$个,使得任意两个不相邻。由于$f[1][1]=n$那么这$y$个集合的排列已经计算了,所以现在可以假设这$y$个元素的第一个放在$m$个位置的第一个位置,那么第二个位置也不能放置了。所以还剩$m-2$个位置,$y-1$个元素。由于每放置一个元素其后面的位置就不能放置了,所以可以把剩下$y-1$个元素的位置与其后面相邻的位置绑定成一个位置,这样的话,就是$m-2-(y-1)$个位置,$y-1$个元素,即$C_{m-2-(y-1)}^{y-1}=C_{n-(x-y)-2-(y-1)}^{y-1}=C_{n-x-1}^{y-1}$

code for problem1

#include <cmath>
#include <string>
#include <vector> class PalindromePermutations {
public:
double palindromeProbability(const std::string &word) {
std::vector<int> h(26, 0);
for (auto e : word) {
++h[e - 'a'];
}
int old_idx = -1;
for (int i = 0; i < 26; ++i) {
if (h[i] % 2 == 1) {
if (old_idx != -1) {
return 0.0;
}
old_idx = i;
}
}
auto total = Compute(h);
if (old_idx != -1) {
--h[old_idx];
}
for (auto &e : h) {
e /= 2;
}
auto target = Compute(h);
double result = 1.0;
for (int i = 2; i < 50; ++i) {
result *= std::pow(i, target[i] - total[i]);
}
return result;
} private:
std::vector<int> Compute(const std::vector<int> &h) {
std::vector<int> result(50, 0);
auto Add = [&](int x, int sgn) {
for (int i = 2; i <= x; ++i) {
int k = i;
for (int j = 2; j * j <= k; ++j) {
while (k % j == 0) {
result[j] += sgn;
k /= j;
}
}
if (k != 1) {
result[k] += sgn;
}
}
};
int n = 0;
for (auto e : h) {
Add(e, -1);
n += e;
}
Add(n, 1);
return result;
}
};

code for problem2

#include <limits>
#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 BlockTheBlockPuzzle {
static constexpr int kInfinite = 1000000; public:
int minimumHoles(const std::vector<std::string> &S) {
MaxFlowSolver<int> solver;
int n = static_cast<int>(S.size());
int source = -1;
int sink = -2;
int tx = -1, ty = -1;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (S[i][j] == '$') {
tx = i;
ty = j;
}
}
} auto P0 = [&](int i, int j) { return i * n + j; };
auto P1 = [&](int i, int j) { return i * n + j + n * n; }; for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (i % 3 == tx % 3 && j % 3 == ty % 3) {
if (S[i][j] == '$') {
solver.InsertEdge(P1(i, j), sink, kInfinite);
}
if (S[i][j] == 'b') {
solver.InsertEdge(source, P0(i, j), kInfinite);
}
if (S[i][j] != 'H') {
solver.InsertEdge(P0(i, j), P1(i, j),
S[i][j] == '.' ? 1 : kInfinite);
}
if (i + 3 < n) {
auto cost = GetCost(S, i + 1, j, i + 2, j);
solver.InsertEdge(P1(i, j), P0(i + 3, j), cost);
solver.InsertEdge(P1(i + 3, j), P0(i, j), cost);
}
if (j + 3 < n) {
auto cost = GetCost(S, i, j + 1, i, j + 2);
solver.InsertEdge(P1(i, j), P0(i, j + 3), cost);
solver.InsertEdge(P1(i, j + 3), P0(i, j), cost);
}
}
}
}
auto result = solver.MaxFlow(source, sink);
if (result >= kInfinite) {
return -1;
}
return result;
} private:
int GetCost(const std::vector<std::string> &s, int x1, int y1, int x2,
int y2) {
if (s[x1][y1] == 'b' || s[x2][y2] == 'b') {
return kInfinite;
}
int ans = 0;
if (s[x1][y1] == '.') {
++ans;
}
if (s[x2][y2] == '.') {
++ans;
}
return ans;
}
};

code for problem3

constexpr int kMod = 1000000007;
constexpr int kMax = 2000; int f[kMax + 1][kMax + 1];
int C[kMax + 1][kMax + 1]; class Seatfriends {
public:
int countseatnumb(int N, int K, int G) {
f[1][1] = N;
for (int i = 1; i < K; ++i) {
for (int j = 1; j <= G; ++j) {
long long p = f[i][j];
if (p == 0) {
continue;
}
if (j < G) {
(f[i + 1][j + 1] += static_cast<int>(p * j % kMod)) %= kMod;
}
(f[i + 1][j - 1] += static_cast<int>(p * j % kMod)) %= kMod;
(f[i + 1][j] += static_cast<int>(p * 2 * j % kMod)) %= kMod;
}
}
if (K == N) {
return f[K][0];
} C[0][0] = 1;
for (int i = 1; i <= N; ++i) {
C[i][0] = C[i][i] = 1;
for (int j = 1; j < i; ++j)
C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % kMod;
} long long ans = 0;
for (int j = 1; j <= G; ++j) {
ans += static_cast<long long>(f[K][j]) * C[N - K - 1][j - 1] % kMod;
}
return static_cast<int>(ans % kMod);
}
};

topcoder srm 625 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 625 DIV2 IncrementingSequence

    由于题目数据量比较小,故可以开辟一个数组存储每个index出现的次数 然后遍历即可 string canItBeDone(int k, vector<int> A){ vector< ...

  8. topcoder SRM 625 DIV2 AddMultiply

    由于题目告诉肯定至少存在一种解, 故只需要根据条件遍历一下, vector <int> makeExpression(int y) { vector<int> res; ; i ...

  9. Topcoder SRM 584 DIV1 600

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

随机推荐

  1. zookeeper 日志输出到指定文件夹

    最近在研究Zookeeper Storm Kafka, 顺便在本地搭了一套集群, 遇到了Zookeeper日志问题输出路径的问题, 发现zookeeper设置log4j.properties不能解决日 ...

  2. Java-多态经典例子

    public class A { public String show(D obj) { return ("A and D"); } public String show(A ob ...

  3. kettle获取系统时间

    Date.prototype.Format = function (fmt) { //author: meizz var o = { "M+": this.getMonth() + ...

  4. oracle_创建表空间_临时表空间_修改表空间_以及自增长

    管理员用户登录oracle数据库 [oracle@DBORACLE ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.4.0 Production on ...

  5. STM32 内部flash的读写程序

    ​ /* Base address of the Flash sectors */ #define ADDR_FLASH_SECTOR_0 ((uint32_t)0x08000000) /* Base ...

  6. vi命令插入

    1.插入 i :在当前光标前插入 I:在当前行的行首插入 a:在当前光标后插入 A:在当前行的行尾插入 o:在当前行的下面另起一行插入 O:在当前行的上面另起一行插入 s:删除当前光标的字符并开始插入 ...

  7. JDBC(Java Data Base Connectivity,java数据库连接)

    JDBC概述 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言 ...

  8. zt (stack overflow 介绍)

    这是「解密 Stack Overflow 架构」系列的第一篇,本系列会有非常多的内容.欢迎阅读并保持关注. 为了便于理解本文涉及到的东西到底都干些了什么,让我先从 Stack Overflow 每天平 ...

  9. 检测U盘插入、拨出状态

    头文件 #include <Dbt.h> 关键代码: LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LP ...

  10. cycle标签和random两种方式美化表格

    一:cycle标签实现给表格变色 1. <style>标签里写好需要的颜色 2. 在要变色的地方(行/列)加固定的语句,按照顺序依次执行 代码: <!DOCTYPE html> ...