problem1 link

因为数据比较小,直接开一个二维数组记录哪些格子已经遍历,哪些还没有。进行模拟即可。

problem2 link

模拟一些小数据,可以发现,AB的形状以及要求的区间是下面的样子:

对于每个答案中的格子,直接去找它是哪种格子即可。每一次$x$都会变为原来的三分之一。

problem3 link

首先,可以求出需要的最少改变的次数。在最少的改变次数之后的改变一定是对每个改变的位置改变了至少三次(3的倍数),这样的话代价一定是$costs[0]+costs[1]+costs[2]$的倍数。所以可以求出最多的改变次数,设为$K$。

设$d_{1}$表示当前多少个位置需要$3t+1$步才能完成,$d_{2}$表示当前多少个位置需要$3t+2$步才能完成.那么需要$3t$步的位置为$n-d_{1}-d_{2}$.$n$为串的长度。每次修改的转移是:

(1)修改了$d_{2}$中的一个,那么转移为$(d_{1},d_{2})$到($d_{1}+1,d_{2}-1)$

(2)修改了$d_{1}$中的一个,那么转移为$(d_{1},d_{2})$到($d_{1}-1,d_{2})$

(1)修改了$n-d_{1}-d_{2}$中的一个,那么转移为$(d_{1},d_{2})$到($d_{1},d_{2}+1)$

现在二元组$(d_{1},d_{2})$可以表示一个状态,所有的状态最多有$p=\frac{(n+1)(n+2)}{2}$。将状态编号。所有转移可以用一个矩阵表示。现在可以得到一个转移的矩阵$A$,那么答案就是$A^{0}+A^{1}+...+A^{K}$,这个可以用二分计算,复杂度为$log(K)*p^{3}$.

这里有一个优化是增加一个状态表示“成功”,设其编号为$p+1$,设状态$(0,0)$的编号为$q$,那么$A[q][p+1]=1,A[p+1][p+1]=1$。这样计算$A^{K+1}$即可。

code for problem1

#include <stdio.h>
#include <iostream>
#include <vector>
using namespace std; class RotatingBot {
public:
int minArea(vector<int> moves) {
int min_x = 0;
int max_x = 0;
int min_y = 0;
int max_y = 0;
int dx[] = {0, -1, 0, 1};
int dy[] = {1, 0, -1, 0};
int current_x = 0;
int current_y = 0;
int current_direction = 0;
std::vector<Segment> pre_segments; auto Go = [&](int step) {
int next_x = current_x + dx[current_direction] * step;
int next_y = current_y + dy[current_direction] * step;
Segment current_segment{current_x, current_y, next_x, next_y};
pre_segments.push_back(current_segment);
min_x = std::min(min_x, next_x);
max_x = std::max(max_x, next_x);
min_y = std::min(min_y, next_y);
max_y = std::max(max_y, next_y);
current_direction = (current_direction + 1) & 3;
current_x = next_x;
current_y = next_y;
}; for (size_t i = 0; i < moves.size() && i < 4; ++i) {
Go(moves[i]);
}
if (moves.size() <= 3) {
return (max_x - min_x + 1) * (max_y - min_y + 1);
}
if (pre_segments[3].y2 > 0) {
return -1;
} else if (pre_segments[3].y2 == 0) {
if (pre_segments[3].y2 == 0 &&
(pre_segments[3].x2 >= 0 ||
((moves.size() > 4) && (pre_segments[3].x2 < -1)))) {
return -1;
}
} else {
if (moves.size() > 4 && pre_segments[3].x2 < 0) {
return -1;
}
} const int N = max_x - min_x + 1;
const int M = max_y - min_y + 1;
std::vector<std::vector<bool>> grid(N, std::vector<bool>(M, false));
auto Fill = [&](const Segment &s) {
if (s.x1 == s.x2) {
for (int i = std::min(s.y1, s.y2); i <= std::max(s.y1, s.y2); ++i) {
grid[s.x1][i] = true;
}
} else {
for (int i = std::min(s.x1, s.x2); i <= std::max(s.x1, s.x2); ++i) {
grid[i][s.y1] = true;
}
}
}; auto FindEnd = [&](int x, int y, int direction) -> std::pair<int, int> {
do {
int new_x = x + dx[direction];
int new_y = y + dy[direction];
if (new_x < 0 || new_x >= N || new_y < 0 || new_y >= M ||
grid[new_x][new_y]) {
return {x, y};
}
x = new_x;
y = new_y;
} while (true);
}; for (Segment &s : pre_segments) {
s.Move(-min_x, -min_y);
Fill(s);
}
current_x -= min_x;
current_y -= min_y;
max_x -= min_x;
max_y -= min_y;
min_x = min_y = 0;
for (size_t i = 4; i < moves.size(); ++i) {
auto end = FindEnd(current_x, current_y, current_direction);
int direction = current_direction;
Go(moves[i]);
Segment s = pre_segments.back();
if (direction == 0) {
if (s.y2 > end.second ||
((i + 1 < moves.size()) && (s.y2 < end.second))) {
return -1;
}
} else if (direction == 1) {
if (s.x2 < end.first ||
((i + 1 < moves.size()) && (s.x2 > end.first))) {
return -1;
}
} else if (direction == 2) {
if (s.y2 < end.second ||
((i + 1 < moves.size()) && (s.y2 > end.second))) {
return -1;
}
} else {
if (s.x2 > end.first ||
((i + 1 < moves.size()) && (s.x2 < end.first))) {
return -1;
}
}
Fill(s);
}
return (max_x - min_x + 1) * (max_y - min_y + 1);
} private:
struct Segment {
int x1;
int y1;
int x2;
int y2; void Move(int diff_x, int diff_y) {
x1 += diff_x;
x2 += diff_x;
y1 += diff_y;
y2 += diff_y;
}
};
};

code for problem2

#include <iostream>
#include <string>
#include <vector>
using namespace std; class CheckerExpansion {
public:
vector<string> resultAfter(long long t, long long x0, long long y0, int w,
int h) {
std::vector<std::string> result(h);
for (int i = 0; i < h; ++i) {
std::string s = "";
for (int j = 0; j < w; ++j) {
s += Compute(t, x0 + j + 1, y0 + h - i - 1 + 1);
}
result[i] = s;
}
return result;
} private:
char Compute(long long t, long long x, long long y) {
if (x + y > t + t) {
return '.';
}
long long current_width = 1L;
long long current_height = 1L;
while (current_width < x || current_height < y) {
current_width = (current_width << 1) + 1;
current_height <<= 1;
} auto IsInside = [](long long x, long long y, long long width,
long long height) {
return 1 <= x && x <= width && 1 <= y && y <= height &&
x + y <= height + height && x >= y;
}; while (current_width > 3) {
long long width = current_width >> 1;
long long height = current_height >> 1;
if (IsInside(x, y, width, height)) {
} else if (IsInside(x - width - 1, y, width, height)) {
x -= width + 1;
} else if (IsInside(x - height, y - height, width, height)) {
x -= height;
y -= height;
} else {
return '.';
}
current_width = width;
current_height = height;
}
if (x == 1 && y == 1) {
return 'A';
}
if ((x == 2 && y == 2) || (x == 3 && y == 1)) {
return 'B';
}
return '.';
}
};

  

code for problem3

#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std; class ConversionMachine {
static constexpr int mod = 1000000007;
using Matrix = std::vector<std::vector<int>>; public:
int countAll(string word1, string word2, vector<int> costs, int maxCost) {
auto ComputeCost = [&](char from, char to) -> long long {
int id1 = static_cast<int>(from - 'a');
int id2 = static_cast<int>(to - 'a');
long long result = 0;
while (id1 != id2) {
result += static_cast<long long>(costs[id1]);
id1 = (id1 + 1) % 3;
}
return result;
};
auto ComputeDist = [&](char from, char to) -> int {
int id1 = static_cast<int>(from - 'a');
int id2 = static_cast<int>(to - 'a');
return (id2 - id1 + 3) % 3;
}; const int N = static_cast<int>(word1.size());
long long total_moves = 0;
int type1 = 0;
int type2 = 0;
for (int i = 0; i < N; ++i) {
long long r = ComputeCost(word1[i], word2[i]);
if (static_cast<long long>(maxCost) < r) {
return 0;
}
int t = ComputeDist(word1[i], word2[i]);
total_moves += t;
if (t == 1) {
++type1;
} else if (t == 2) {
++type2;
}
maxCost -= static_cast<int>(r);
}
long long total = static_cast<long long>(costs[0]) +
static_cast<long long>(costs[1]) +
static_cast<long long>(costs[2]);
total_moves += static_cast<long long>(maxCost) / total * 3;
std::map<std::pair<int, int>, int> index_map;
int index = 0;
for (int d1 = 0; d1 <= N; ++d1) {
for (int d2 = 0; d1 + d2 <= N; ++d2) {
index_map[std::make_pair(d1, d2)] = index++;
}
}
index++;
Matrix transform_table(index, std::vector<int>(index, 0));
for (auto &from : index_map) {
int d1 = from.first.first;
int d2 = from.first.second;
int id = from.second;
if (d2 > 0) {
transform_table[id][index_map[std::make_pair(d1 + 1, d2 - 1)]] = d2;
}
if (d1 > 0) {
transform_table[id][index_map[std::make_pair(d1 - 1, d2)]] = d1;
}
if (N - d1 - d2 > 0) {
transform_table[id][index_map[std::make_pair(d1, d2 + 1)]] =
N - d1 - d2;
}
}
transform_table[index_map[{0, 0}]][index - 1] = 1;
transform_table[index - 1][index - 1] = 1;
Matrix result_table = Pow(transform_table, total_moves + 1);
int from_idx = index_map[std::make_pair(type1, type2)];
return result_table[from_idx][index - 1];
} private:
Matrix UnitMatrix(size_t n) {
Matrix r(n, std::vector<int>(n, 0));
for (size_t i = 0; i < n; ++i) {
r[i][i] = 1;
}
return r;
}
Matrix Pow(Matrix t, long long p) {
Matrix r = UnitMatrix(t.size());
while (p > 0) {
if ((p & 1) == 1) {
r = Multiply(r, t);
}
t = Multiply(t, t);
p >>= 1;
}
return r;
} Matrix Multiply(const Matrix &left, const Matrix &right) {
Matrix r(left.size(), std::vector<int>(left.size(), 0));
for (size_t i = 0; i < left.size(); ++i) {
for (size_t j = 0; j < left.size(); ++j) {
for (size_t k = 0; k < left.size(); ++k) {
int t = static_cast<int>(static_cast<long long>(left[i][k]) *
static_cast<long long>(right[k][j]) % mod);
Add(r[i][j], t);
}
}
}
return r;
}
void Add(int &x, int y) {
x += y;
if (x >= mod) {
x -= mod;
}
}
};

  

topcoder srm 550 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 550

    div1 250pt: 题意:有个机器人,从某一点出发,他只有碰到地形边缘或者碰到走过的点时才会改变运动方向,然后接着走,现在给出他的运动轨迹,判断他的运动是否合法,如果合法的话,那么整个地形的最小面 ...

  7. Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串

    Problem Statement      The Happy Letter game is played as follows: At the beginning, several players ...

  8. Topcoder SRM 584 DIV1 600

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

  9. TopCoder SRM 605 DIV1

    604的题解还没有写出来呢.先上605的. 代码去practice房间找. 说思路. A: 贪心,对于每个类型的正值求和,如果没有正值就取最大值,按着求出的值排序,枚举选多少个类型. B: 很明显是d ...

随机推荐

  1. caffe中关于(ReLU层,Dropout层,BatchNorm层,Scale层)输入输出层一致的问题

    在卷积神经网络中.常见到的激活函数有Relu层 layer { name: "relu1" type: "ReLU" bottom: "pool1&q ...

  2. 水题 O

    Bob 和 Alice 开始使用一种全新的编码系统.它是一种基于一组私有钥匙的.他们选择了n个不同的数a1 , . . .,an, 它们都大于0小于等于n. 机密过程如下:待加密的信息放置在这组加密钥 ...

  3. Buffer、ArrayBuffer、DataView互转(node.js)

    1.Buffer转ArrayBuffer // 实例一 const buf = Buffer.from("this is a test"); console.log(buf); c ...

  4. DX9 顶点缓存案例

    // @time 2012.3.5 // @author jadeshu //包含头文件 #include <Windows.h> #include <d3d9.h> #pra ...

  5. kali漏洞扫描

    nmap (apt-get install nmap)          nmap从初级到高级 ------------------------------ Nessus (dpkg -i Nessu ...

  6. C#深入研究ArrayList动态数组自动扩容原理

    1 void Test1() { ArrayList arrayList = new ArrayList(); ; ; i < length; i++) { arrayList.Add(&quo ...

  7. hdu5294 网络流+dijskstr

    题意:给你n个墓室,m条路径,一个人在1号墓室(起点),另一个人在n号墓室(终点),起点的那个人只有通过最短路径才能追上终点的那个人,而终点的那个人能切断任意路径. 第一问——终点那人要使起点那人不能 ...

  8. codeforces 980C Posterized

    题意: 255个像素格子,可以把这个255个分组,每组的大小不能超过k. 给出n个像素,要求每个像素用这组的key代表,并且表示出来的字典序要最小. 思路: 感谢js教本智障. 很自然的会想到贪心,也 ...

  9. SQL Server 配置管理器

  10. PYQT5学习笔记之各模块介绍

    Qtwidgets模块包含创造经典桌面风格的用户界面提供了一套UI元素的类 Qtwidegts下还有以下常用对象,所以一般使用Qtwidegts时会使用面向对象式编程 QApplication: ap ...