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. markdown入门杂记

    系统环境:win10 软件:sublime Text 3 安装插件: markdown editing.markdownlivepreview 修改prference-markdownliveprev ...

  2. Linux(Centos)服务器配置node项目

    以阿里云服务器,CentOS系统为例 上一节已经提到怎么安装nodejs,以下是以vue项目为例 步骤: (1)首先安装vue脚手架@vue/cli, 官网参考 vue-cli3.x [root@lu ...

  3. UGUI 打图集

    using UnityEngine; using System.Collections; using UnityEditor; using System.Collections.Generic; us ...

  4. mysql 5.6 分区与不分区的区别

    mysql> CREATE TABLE t1 ( id INT, date DATETIME DEFAULT CURRENT_TIMESTAMP) ENGINE=Innodb; Query OK ...

  5. CNN超参数优化和可视化技巧详解

    https://zhuanlan.zhihu.com/p/27905191 在深度学习中,有许多不同的深度网络结构,包括卷积神经网络(CNN或convnet).长短期记忆网络(LSTM)和生成对抗网络 ...

  6. CSS尺寸与补白属性-----margin和padding

       margin margin:[ <length> | <percentage> | auto ]{1,4}  为元素设置所有四个方向(上右下左)的外边距 auto:水平( ...

  7. spring 源码导入eclipse(sts)

    一. 准备工作 1.下载安装sts(springsource推荐使用) 下载地址: http://www.springsource.org/downloads/sts-ggts 2.下载安装gradl ...

  8. 第三方统计分析埋点工具对比,神策、Ptmind、GrowingIO、国双,还有谷歌分析,谁更好?

    第三方统计分析埋点工具对比,神策.Ptmind.GrowingIO.国双,还有谷歌分析,谁更好?https://www.colabug.com/2985393.html GA.Mixpanel 和神策 ...

  9. golang学习笔记15 golang用strings.Split切割字符串

    golang用strings.Split切割字符串 kv := strings.Split(authString, " ") if len(kv) != 2 || kv[0] != ...

  10. linux下php中文UTF-8转换Unicode方法和注意事项

    先说下遇到问题:1.php没有内置unicode_ecode函数可以直接使用 2.网上很多资料都是用$str = iconv($encoding, 'UCS-2', $str); window下转换出 ...