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. jsp重新打开一个新的页面

    有以下一种实现方式: 1.target="_blank” <a href="document.html" target="_blank"> ...

  2. docker-php-ext-install.md(https://gist.github.com/giansalex/2776a4206666d940d014792ab4700d80)

    ```bash RUN apt update RUN apt upgrade -y RUN apt install -y apt-utils RUN a2enmod rewrite RUN apt i ...

  3. Beta冲刺阶段5.0

    1. 提供当天站立式会议照片一张 2. 每个人的工作 (有work item 的ID) 成员 昨天已完成的工作 今天计划完成的工作 工作中遇到的困难 具体贡献 郑晓丽 首页活动详情界面的美化 实现首页 ...

  4. <9>cc.Sprite组件

    1.精灵 精灵(Sprite)是Cocos系列的核心概念之一,是Cocos Creator最常用的显示图像的组件. 游戏中显示一个图片,我们就可以把这个叫做”精灵” sprite,这只是简单理解概念. ...

  5. os.system

    python   os.system os.system()函数在不同的系统下可以实现不同的作用 一.window下: os.system("ping www.baidu.com" ...

  6. html5-css的引入

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  7. jQuery选择器--:first和:last

       :first 概述 获取匹配的第一个元素    :last 概述 获取匹配的最后个元素 <!DOCTYPE html> <html> <head> <m ...

  8. Nginx技术研究系列2-基于Redis实现动态路由

    上篇博文我们写了个引子: Ngnix技术研究系列1-通过应用场景看Nginx的反向代理 发现了新大陆,OpenResty OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台 ...

  9. 【Hive学习之六】Hive Lateral View &视图&索引

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 jdk8 hadoop-3.1.1 apache-hive-3.1.1 ...

  10. TMC首秀:写作带给我生命的影响与感动

    蓦然回首,写作已陪伴了我十三个年头,横跨大学.读研.工作之初.直到现在.我将分四个小乐章,分享写作给我的生命带来的影响和感动. 第一乐章:治疗与励志 说起写作的缘由,虽然可以追溯到初高中时读过的一点文 ...