problem1 link

最后剩下的是中间的一个矩形.所以可以直接枚举这个矩形,如果它含有的硬币个数等于$K$,则再计算移动的最少次数,更新答案.

problem2 link

首先,每个节点发送每种消息最多只发送一次;其次,在得到消息之后一定是马上发送而不是等待一会儿再发送;最后一点是,如果第$i$天发送了一种消息,一定可以在第$i+1$天发送另外一种消息.

现在的问题是,一个节点同时有两种消息时,应该首先发送哪一种.这个可以$2^{n}$枚举第一次发送的消息类型,然后模拟即可.在模拟过程中可能会出现先来的消息不是枚举的第一次发送的类型.这个可以直接结束这种情况,因为一定会枚举到一种情况,其他节点都一样,而这个节点是先发送另一种状态.

problem3 link

首先,如果将给出的矩阵看作是$n$个顶点的有向图,那么交换$i,j$行列得到的新图相当于两个顶点交换标号,即顶点$i$变为$j$,顶点$j$变为$i$.

那么题目就是要对给出的图重新标号,使得与目标图匹配.

对于$n=8$来说,如果画出目标图,是下面的样子:

设$p_{i}$表示目标图的第$i$个顶点是原图的第$p_{i}$个顶点.那么对于$n=8$来说,确定了$p_{0},p_{1},p_{n-1}$后,与$p_{1}$相连且不与$p_{n-1}$相连的就是$p_{2}$,同时与$p_{1}$和$p_{n-1}$相连的是$p_{6}$.

也就是说由$p_{1},p_{7}$可找到$p_{2},p_{6}$.同理,由$p_{2},p_{6}$可找到$p_{3},p_{5}$,最后就是$p_{4}$.查找的过程如下图所示(第一幅图找到$p_{2},p_{6}$,第二幅图找到$p_{3},p_{5}$)

最后一个问题就是如果有了这个数组$p$,求最少的交换次数.$p$中的数组组成了若干个环,对于每个环$C$,需要的交换次数为$|C|-1$

code for problem1

#include <vector>
#include <string>
#include <algorithm>
using namespace std; class DropCoins {
public:
int getMinimum(vector <string> board, int K) {
const int n = (int)board.size();
const int m = (int)board[0].size();
int result = -1;
vector<vector<int>> f(n + 1, vector<int>(m + 1, 0));
for (int i = 1; i <= n; ++ i) {
for (int j = 1; j <= m; ++ j) {
f[i][j] = f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1];
if (board[i - 1][j - 1] == 'o') {
++ f[i][j];
}
}
}
for (int left = 1; left <= m; ++ left) {
for (int right = left; right <= m; ++ right) {
for (int up = 1; up <= n; ++ up) {
for (int down = up; down <= n; ++ down) {
int cnt = f[down][right] - f[down][left - 1] - f[up - 1][right]
+ f[up - 1][left - 1];
if (cnt == K) {
int cost = Cost(left - 1, m - right) + Cost(up - 1, n - down);
if (result == -1 || result > cost) {
result = cost;
}
}
}
}
}
}
return result;
} private:
int Cost(int x, int y) {
return std::min(x + x + y, x + y + y);
}
};

code for problem2

#include <iostream>
#include <string>
#include <vector>
using namespace std; class Rumor {
public:
int getMinimum(string knowledge, vector<string> graph)
{
const int n = (int)graph.size();
int result = -1;
for (int mask = 0; mask < (1 << n); ++ mask) {
int cost = calculate(mask, knowledge, graph);
if (cost != -1 && (result == -1 || result > cost)) {
result = cost;
}
}
return result;
} private: int getFirstType(int mask, int i) {
return (mask & (1 << i)) ? 2 : 1;
}
int getSecondType(int mask, int i) {
return (mask & (1 << i)) ? 1 : 2;
}
int calculate(const int mask, const string& knowledge,
const vector<string>& graph) {
const int n = (int)knowledge.size();
long long preGetMessageState = 0;
long long currentKnowMessageState = 0;
int preBroadcastMask = 0;
int day = 0;
for (int i = 0; i < n; ++ i) {
if (knowledge[i] == 'Y') {
preGetMessageState |= 3ll << (i << 1);
}
}
int sendedMessageMask = 0;
currentKnowMessageState = preGetMessageState;
const long long finalState = (1ll << (n + n)) - 1;
while (currentKnowMessageState != finalState) {
++ day;
int nowBroadcastState = 0;
long long nowGetMessageState = 0;
for (int i = 0; i < n; ++ i) {
int type = -1;
if (preBroadcastMask & (1 << i)) {
type = getSecondType(mask, i);
}
else if (!(sendedMessageMask & (1 << i))) {
int t = (preGetMessageState >> (i + i)) & 3;
if (t != 0) {
if (t & getFirstType(mask, i)) {
type = getFirstType(mask, i);
}
else {
return -1;
}
}
}
if (type == -1) {
continue;
}
for (int j = 0; j < n; ++ j) {
if (graph[i][j] == 'Y') {
nowGetMessageState |= ((long long)type) << (j + j);
}
}
if (type == getSecondType(mask, i)) {
sendedMessageMask |= 1 << i;
}
else {
nowBroadcastState |= 1 << i;
}
}
long long currentAll = currentKnowMessageState | nowGetMessageState;
if (currentAll == currentKnowMessageState) {
return -1;
}
currentKnowMessageState = currentAll;
preGetMessageState = nowGetMessageState;
preBroadcastMask = nowBroadcastState;
}
return day;
}
};

code for problem3

#include <vector>
#include <string>
#include <algorithm>
using namespace std; class MonochromePuzzle {
public:
int getMinimum(vector <string> board) {
const int n = (int)board.size();
for (int i = 0; i < n; ++ i) {
int cnt = 0;
for (int j = 0; j < n; ++ j) {
if (board[i][j] == '#') {
++ cnt;
}
}
if (cnt != 3) {
return -1;
}
}
int result = -1;
for (int i = 0; i < n; ++ i) {
for (int j = 0; j < n; ++ j) {
if (i == j) {
continue;
}
for (int k = 0; k < n; ++ k) {
if (k == i || k == j) {
continue;
}
if (board[i][j] != '#' || board[i][k] != '#') {
continue;
}
int tmp = calculate(i, j, k, board);
if (tmp != -1 && (result == -1 || result > tmp)) {
result = tmp;
}
}
}
}
return result;
}
private:
int calculate(const int p0, const int p1, const int p2,
const vector<string>& board) {
const int n = (int)board.size();
vector<int> p(n, 0);
vector<int> used(n, 0);
p[0] = p0;
p[1] = p1;
p[n - 1] = p2;
used[p0] = used[p1] = used[p2] = 1;
int x = 1, y = n - 1;
int a = 2, b = n - 2;
while (a < b) {
int ta = -1, tb = -1;
for (int i = 0; i < n; ++ i) {
if (used[i] == 0 && board[p[x]][i] == '#') {
if (board[p[y]][i] == '#') {
tb = i;
}
else {
ta = i;
}
}
}
if (ta == -1 || tb == -1) {
return -1;
}
p[a] = ta;
p[b] = tb;
used[ta] = used[tb] = 1;
x = a ++;
y = b --;
}
for (int i = 0; i < n; ++ i) {
if (used[i] == 0 && board[p[x]][i] == '#' &&
board[p[y]][i] == '#' && board[p[n - 1]][i] == '#') {
p[a] = i;
return getCost(p);
}
}
return -1;
}
int getCost(const vector<int>& p) {
const int n = (int)p.size();
vector<int> visited(n, 0);
int result = n;
for (int i = 0; i < n; ++ i) {
if (visited[i]) {
continue;
}
int current = i;
while (visited[current] == 0) {
visited[current] = 1;
current = p[current];
}
result -= 1;
}
return result;
}
};

  

topcoder srm 525 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. Spark实战记录

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~PipelineExample winutils.exe java.lang.NullPointException~~~~~~~~~~~~~ ...

  2. 从0开始搭建vue+webpack脚手架(三)

    在从0开始搭建vue+webpack脚手架(二)中已经基本完成了开发环境的配置.当开发完成后,我们需要将完成的项目进行打包,接下来对打包做一些优化: 运行 $ npm run build 可生成dis ...

  3. vsftp

    [安装vsftpd]安装vsftpd工具步骤   1 安装vsftpd组件 [root@bogon ~]# yum -y install vsftpd 安装完后,有/etc/vsftpd/vsftpd ...

  4. caffe深度学习进行迭代的时候loss曲线开始震荡原因

    1:训练的batch_size太小 1.       当数据量足够大的时候可以适当的减小batch_size,由于数据量太大,内存不够.但盲目减少会导致无法收敛,batch_size=1时为在线学习. ...

  5. mysql 知识

    1.  数据库事务的四个特性及含义 数据库事务transanction正确执行的四个基本要素.ACID,原子性(Atomicity).一致性(Correspondence).隔离性(Isolation ...

  6. yum 与 apt 的对比

    一.概念 使用yum/apt之前,你很可能会遇到配置源(ubuntu下一般内置的就比较好,所以可能很少人手动配置),那这个源是什么呢,就是告诉apt/yum,安装软件的时候你要从哪里下载.比如你使用1 ...

  7. maven 常用 Archetypes

    maven 常用 Archetypes Archetypes简介 什么是原型? 简而言之,Archetype是一个Maven项目模板工具包.原型被定义为原始模式或模型,从中创建所有其他相同类型的东西. ...

  8. RSA解密解密

    #!/usr/bin/env python # -*- coding:utf-8 -*- import rsa import base64 # ######### 1. 生成公钥私钥 ######## ...

  9. Python 字典(Dictionary) values()方法

    描述 Python 字典(Dictionary) values() 函数以列表返回字典中的所有值. 语法 values()方法语法: dict.values() 参数 NA. 返回值 返回字典中的所有 ...

  10. python 创建临时文件和文件夹

    ----需要在程序执行时创建一个临时文件或目录,并希望使用完之后可以自动销毁掉. tempfile 模块中有很多的函数可以完成这任务.为了创建一个匿名的临时文件,可以使用tempfile.Tempor ...