topcoder srm 625 div1
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的更多相关文章
- 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 625 DIV2 IncrementingSequence
由于题目数据量比较小,故可以开辟一个数组存储每个index出现的次数 然后遍历即可 string canItBeDone(int k, vector<int> A){ vector< ...
- topcoder SRM 625 DIV2 AddMultiply
由于题目告诉肯定至少存在一种解, 故只需要根据条件遍历一下, vector <int> makeExpression(int y) { vector<int> res; ; i ...
- Topcoder SRM 584 DIV1 600
思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...
随机推荐
- Express全系列教程之(八):session的基本使用
一.关于session session是另一种记录客户状态的机制,与cookie保存在客户端浏览器不同,session保存在服务器当中:当客户端访问服务器时,服务器会生成一个session对象,对象中 ...
- 新手上路、安装JDK教程
按照以下的图片步骤,登录http://www.oracle.com 下载 JDK (J2SE) JDK 1.0, 1.1, 1.2, 1.3, 1.4 1.5.(JDK5.0) → 支持注解. ...
- 【Linux】Mac Centos install VMware Tools
can't use yum: vi /etc/sysconfig/network-scripts/ifcfg-enp4s0 yum -y install lshw pciutils gdisk sys ...
- win 下 python ImportError: No module named requests
第一次弄爬虫,报库找不到,网上找了半天,一般都让都让改成绝对路径...那不是饮鸩止渴嘛. 然后 在无意中发现,不需要控制台输入pip命令,因为不是在Linux下啊,,win下直接在pycharm里添加 ...
- .htaccess使用方法介绍
1..htaccess文件使用前提 .htaccess的主要作用就是实现url改写,也就是当浏览器通过url访问到服务器某个文件夹时,作为主人,我们可以来接待这个url,具体地怎样接待它,就是此文件的 ...
- 我的第三篇博客(激动激动真激动!!!)A-B Problem
#210. 差(A-B problem) 题目描述 楠楠在网上刷题,感觉第一题:求两数的和(A+B Problem)太无聊了,于是增加了一题:A-B Problem,难倒了一群小朋友,哈哈. 题目是这 ...
- Sublime 个人常用快捷键
Sublime 个人常用快捷键 Hot Key Alt + F3 选中文本所以有相同项;同多次Ctrl + D Ctrl + L 选中整行,继续按可继续选 Ctrl + Shift + M 选择括号内 ...
- Linux 7.x 防火墙&端口
Linux 7.x 防火墙&端口 查看当前防火墙的状态: # firewall-cmd --state 也可以使用指令:systemctl status firewall.service 启动 ...
- Go 初体验 - 并发与锁.1 - sync.Mutex 与 sync.RWMutex
==== Mutex为互斥锁,顾名思义,被Mutex锁住的代码同时只允许一个协程访问,其它协程进来就要排队 如何使用?看代码: 输出: 释义: 并发1000个协程同时更改m的元素,这样会有一部分更改成 ...
- HTTP协议基础总结
1,HTTP协议协议的概念:协议就是指计算机网络中,两台计算机之间进行通讯所必须共同遵守的规定和规则.HTTP协议:超文本传输协议是一种通信协议,它允许将超文本标记语言(html)文档从web服务器传 ...