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 714 div1

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

  2. topcoder srm 691 div1 -3

    1.给定一个$n$个顶点$n$个边的图,边是$(i,a_{i})$,顶点编号$[0,n-1]$.增加一个顶点$n$,现在选出一个顶点集$M$,对于任意的在$M$中 的顶点$x$,去掉边$(x,a_{x ...

  3. topcoder srm 706 div1

    1.给定一个迷宫,点号表示不可行,井号表示可行.现在可以改变其中的一些井号的位置.问最少改变多少个井号可以使得从左上角到右下角存在路径. 思路:设高为$n$,宽为$m$,若井号的个数$S$小于$n+m ...

  4. topcoder srm 694 div1 -3

    1.给出$n$个数字,将其分成三个非空的组,每组的权值为该组所有数字的抑或.选择一种分法使得三组的权值和最大? 思路:记录前两组的权值且三组有没有数字时第三组的值.(当前两组的值知道时第三组的权值是确 ...

  5. topcoder srm 330 div1

    problem1 link 直接模拟. import java.util.*; import java.math.*; import static java.lang.Math.*;public cl ...

  6. topcoder srm 360 div1

    problem1 link (1)$n \neq m$时,假设$n<m$,那么同一行中的$m$个数字必定都相等. (2)$n=m$时,要满足任意的$i_{1},i_{2},j_{1},j_{2} ...

  7. topcoder srm 635 div1

    problem1 link 首先枚举长度$L$.然后计算每一段长度$L$的差值最大公约数,然后差值除以最大公约数的结果可以作为当前段的关键字.然后不同段就可以比较他们的关键字,一样就是可以转化的. p ...

  8. topcoder srm 495 div1

    problem1 link 从前向后确定一下,然后再从后向前确定一下.一样的话就是可以确定的. problem2 link 首先将强连通分量缩点.理论上来说,只需要遍历所有入度为0的联通块中的一个即可 ...

  9. topcoder srm 325 div1

    problem1 link $g[i]$表示解决前$i$个的代价,那么$g[i]$是所有$g[j]+cost(j+1,i)$的最小值. import java.util.*; import java. ...

最新文章

  1. 极限编程 (Extreme Programming) 和用户故事 (User Stories) 的关系
  2. ASP.NET实现用户在线检测的类源码[转收藏]
  3. 使用Python编写简易定时器
  4. 关于SQL的Group By
  5. POJ_2828 Buy Ticket(线段树)
  6. (转载)New poker 2总算放出新固件了!
  7. 超简单使用阿里云注册商标
  8. 信息检索与利用(第三版)第二章信息资源与信息源
  9. DNS 文件传输协议
  10. Unity的UGUI用TexturePacker全自动打图集,包括九宫格切图信息
  11. IEEE latex 编写lemma
  12. Windows 8 简体中文 官方正式版 原版镜像下载
  13. OLYMP‘ARTS 2023奥艺大会中国推介会在北京盛大举行
  14. 白盒测试---讲解(1)
  15. python听歌识曲爬虫_【python爬虫】 爬云音乐我和xxx共同听过的歌曲
  16. 项目kick-off meeting流程总结(涉外)
  17. playcanvas关于跨域的问题
  18. C++ OpenCV特征提取之KAZE和AKAZE的匹配
  19. Python快速入门(八)面向对象1:类、对象和封装
  20. c语言习题:华氏度摄氏度比照表

热门文章

  1. flink checkpoint 恢复_干货:Flink+Kafka 0.11端到端精确一次处理语义实现
  2. [Leetcode456]132模式 - 单调栈
  3. cvs有机添加剂检测_美国ECI CVS 电镀添加剂分析仪QL-10EX
  4. excel split函数_Excel 字符串拆分
  5. 订阅号 笔记记录开发 php,微信订阅号开发笔记(五)
  6. 极光推送 android 最新,Android——快速集成极光推送-Go语言中文社区
  7. linux可用的ftp,linuxunix下有很多可用的ftp服务器
  8. 服务器批量修改代码,利用Redis实现多服务器批量操作
  9. 数据结构之树【完善中】
  10. 在前端网页设计中 align 和 valign 两种对齐方式的不同取值区分(持续补充)