agc033
A题意:给你个黑白矩阵,每次黑的周围一圈会变黑,求多少次之后全黑。n <= 1000
解:BFS即可。
#include <bits/stdc++.h> const int N = ;
const int dx[] = {, , -, };
const int dy[] = {, , , -}; struct Node {
int x, y;
Node(int X = , int Y = ) {
x = X;
y = Y;
}
}; int vis[N][N], d[N][N];
char str[N];
std::queue<Node> Q; int main() { int n, m, ans = ;
scanf("%d%d", &n, &m);
for(int i = ; i <= n; i++) {
scanf("%s", str + );
for(int j = ; j <= m; j++) {
if(str[j] == '#') {
Q.push(Node(i, j));
vis[i][j] = ;
d[i][j] = ;
}
}
} while(Q.size()) {
int x = Q.front().x, y = Q.front().y;
Q.pop();
for(int i = ; i < ; i++) {
int tx = x + dx[i], ty = y + dy[i];
if(tx < || ty < || tx > n || ty > m || vis[tx][ty]) {
continue;
}
vis[tx][ty] = ;
d[tx][ty] = d[x][y] + ;
Q.push(Node(tx, ty));
ans = std::max(ans, d[tx][ty]);
}
}
printf("%d\n", ans);
return ;
}
AC代码
B题意:给你个矩阵,初始时有个棋子在(sx,sy)。先后手都有个字符串,每一回合可以选择不走或者按照字符串上的方向走一步。先手想要玩完n回合,后手想要在n回合之内把棋子走出棋盘。谁能如愿以偿呢?n <= 20w
解:发现行列独立。于是考虑行。我们从后往前,维护第i步时棋子在哪些地方会导致在n步内出棋盘。判断一下是否必出棋盘即可。列同理。
#include <bits/stdc++.h> const int N = ; char str1[N], str2[N];
int n; int main() { int n1, n2, x1, x2;
scanf("%d%d%d", &n1, &n2, &n);
scanf("%d%d", &x1, &x2);
scanf("%s%s", str1 + , str2 + ); bool f = ;
int L = , R = n1 + ;
for(int i = n; i >= ; i--) { if(str2[i] == 'L' || str2[i] == 'R') { }
else if(str2[i] == 'D') {
L = std::max(L - , );
}
else {
R = std::min(R + , n1 + );
} if(str1[i] == 'L' || str1[i] == 'R') { }
else if(str1[i] == 'D') {
R = R - ;
}
else {
L = L + ;
}
if(L + >= R) {
f = ;
break;
} }
if(x1 <= L || R <= x1) {
f = ;
}
L = , R = n2 + ;
for(int i = n; i >= && f; i--) { if(str2[i] == 'U' || str2[i] == 'D') { }
else if(str2[i] == 'L') {
R = std::min(R + , n2 + );
}
else {
L = std::max(L - , );
} if(str1[i] == 'U' || str1[i] == 'D') { }
else if(str1[i] == 'L') {
L = L + ;
}
else {
R = R - ;
}
if(L + >= R) {
f = ;
break;
} }
if(x2 <= L || R <= x2) {
f = ;
}
if(f) {
printf("YES\n");
}
else {
printf("NO\n");
}
return ;
}
AC代码
C题意:给你一棵树,每个点上有一个硬币。两个人轮流选择一个有硬币的点,把该点的硬币取走并把其它点的硬币都向这个点挪一步。不能操作者输。问谁输?n <= 20w
解:发现与每个点的具体硬币数量没关系,只跟是否有硬币有关系。然后发现每一次就是删掉所有叶子,但是你可以选择保护一个叶子不被删。我们感性想象一下,发现跟每某个点的伸出去的最长链有关系...
然后考虑直径,别问我怎么想到的...灵光一闪就想到了。发现每次操作之后,直径要么减2要么减1,就算直径改变了,但是长度仍然遵守这个规律。且最后剩下来的是一条单个的直径。于是求出直径长度,sg函数即可。(其实有个规律......)
#include <bits/stdc++.h>
const int N = ;
struct Edge {
int nex, v;
}edge[N << ]; int tp;
int n, e[N], sg[N], f[N], Ans;
inline void add(int x, int y) {
edge[++tp].v = y;
edge[tp].nex = e[x];
e[x] = tp;
return;
}
void DFS(int x, int fa) {
int a = , b = ;
for(int i = e[x]; i; i = edge[i].nex) {
int y = edge[i].v;
if(y == fa) continue;
DFS(y, x);
if(a < f[y] + ) {
b = a;
a = f[y] + ;
}
else {
b = std::max(b, f[y] + );
}
}
Ans = std::max(Ans, std::max(a + b - , a));
f[x] = a;
return;
}
int main() {
int n;
scanf("%d", &n);
for(int i = , x, y; i < n; i++) {
scanf("%d%d", &x, &y);
add(x, y);
add(y, x);
}
DFS(, );
/// cal Ans
sg[] = ;
sg[] = ;
for(int i = ; i <= Ans; i++) {
if(std::min(sg[i - ], sg[i - ]) == ) {
sg[i] = ;
}
else {
sg[i] = ;
}
}
if(sg[Ans]) {
printf("First\n");
}
else {
printf("Second\n");
}
return ;
}
AC代码
D题意:给你一个黑白矩阵,求它的复杂度。定义一个矩阵的复杂度为:纯色矩阵为0,否则横/竖切一刀,这种划分方式的权值为两个子矩阵的复杂度的max。这个矩阵的复杂度为所有划分方式的权值中的最小值 + 1。n <= 185, 5s。
解:考虑到复杂度不会超过2log,于是设fijkl为左边界为i,上下边界为jk,复杂度为l的矩形右边界最远能到的列。转移的时候有一个非常优秀的单调指针,不知道为什么......
#include <bits/stdc++.h> const int N = ; short G[N][N], a[N][N][N][], b[N][N][N][], sum1[N][N], sum2[N][N]; /// a-> b|
char str[N]; inline short get1(short l, short r, short i) { /// |
return sum1[r][i] - sum1[l - ][i];
}
inline short get2(short i, short l, short r) { /// -
return sum2[i][r] - sum2[i][l - ];
} inline void exmax(short &a, const short &b) {
a < b ? a = b : ;
return;
}
inline short Min(const short &a, const short &b) {
return a > b ? b : a;
} int main() { //printf("%d \n", (sizeof(a) * 2 + sizeof(G) + sizeof(str)) / 1048576);
short n, m;
scanf("%hd%hd", &n, &m);
for(register short i(); i <= n; ++i) {
scanf("%s", str + );
for(register short j(); j <= m; ++j) {
G[i][j] = (str[j] == '#');
sum1[i][j] = sum1[i - ][j] + G[i][j];
sum2[i][j] = sum2[i][j - ] + G[i][j];
//printf("%hd %hd G = %hd \n", i, j, G[i][j]);
}
} for(register short l(); l <= n; ++l) {
for(register short r(l); r <= n; ++r) {
short last = -;
for(register short i(m); i >= ; --i) {
short tot(get1(l, r, i));
//printf("tot = %hd \n", tot);
if(tot != && tot != r - l + ) {
a[l][r][i][] = i - ;
last = -;
}
else if(last != tot) {
a[l][r][i][] = i;
last = tot;
}
else {
a[l][r][i][] = a[l][r][i + ][];
}
//printf("a %hd %hd %hd 0 = %hd \n", l, r, i, a[l][r][i][0]);
}
}
} /*for(short l = 1; l <= m; l++) {
for(short r = l; r <= m; r++) {
short last = -1;
for(short i = n; i >= 1; i--) {
short tot = get2(i, l, r);
//printf("tot = %hd \n", tot);
if(tot != r - l + 1 && tot != 0) {
b[i][l][r][0] = i - 1;
last = -1;
}
else if(tot != last) {
b[i][l][r][0] = i;
last = tot;
}
else {
b[i][l][r][0] = b[i + 1][l][r][0];
}
//printf("b %hd %hd %hd 0 = %hd \n", i, l, r, b[i][l][r][0]);
}
}
}*/ if(a[][n][][] == m) {
printf("%hd\n", );
return ;
} for(register short j(); j <= ; ++j) { //printf("------------------- %hd -------------------- \n", j);
for(register short i(m); i >= ; --i) {
for(register short l(); l <= n; ++l) {
short p = l;
for(register short r(l); r <= n; ++r) {
exmax(a[l][r][i][j], a[l][r][i][j - ]);
short t(a[l][r][i][j - ]);
t = a[l][r][t + ][j - ];
exmax(a[l][r][i][j], t);
if(a[l][r][i][j] == m || l == r) continue; for(; p < r; ++p) {
/// p [l, p] [p + 1, r]
t = Min(a[l][p][i][j - ], a[p + ][r][i][j - ]);
// if(a[l][p][i][j - 1] <= a[l][r][i][j]) break;
if(a[l][p][i][j - ] == i - ) break;
if(p == r - || Min(a[l][p + ][i][j - ], a[p + ][r][i][j - ]) < t) {
exmax(a[l][r][i][j], t);
break;
}
} }
}
if(a[][n][][j] == m) {
printf("%hd\n", j);
return ;
}
} /*for(short l = 1; l <= n; l++) {
for(short r = l; r <= n; r++) {
for(short i = 1; i <= m; i++) {
printf("a %hd %hd %hd = %hd \n", l, r, i, a[l][r][i][j]);
}
}
}
printf("--------------- \n");
for(short l = 1; l <= m; l++) {
for(short r = l; r <= m; r++) {
for(int i = 1; i <= n; i++) {
printf("b %hd %hd %hd = %hd \n", i, l, r, b[i][l][r][j]);
}
}
}
puts("");*/
} /*for(register short i = 0; i <= 17; i++) {
if(a[1][n][1][i] == m) {
printf("%hd\n", i);
break;
}
if(b[1][1][m][i] == n) {
printf("%hd\n", i);
break;
}
}*/ return ;
}
AC代码
agc033的更多相关文章
- 【AtCoder】AGC033(A-F)
AGC033 A - Darker and Darker 直接BFS #include <bits/stdc++.h> #define fi first #define se second ...
- AGC033 D~F——[ 值放到角标的DP ][ 思路+DP ][ 思路 ]
地址:https://atcoder.jp/contests/agc033/ D Complexity dp[ i ][ j ][ k ][ l ] 表示左上角是 ( i , j ) .右下角是 ( ...
- AtCoder整理(持续更新中……)
做了那么久的atcoder觉得自己的题解发的很乱 给有想和我一起交流atcoder题目(或者指出我做法的很菜)(或者指责我为什么整场比赛只会抄题解)的同学一个索引的机会??? 于是写了个爬虫爬了下 A ...
随机推荐
- scrpy--分布式爬虫
原来的scrapy中的Scheduler维护的是当前机器中的任务队列(存放着Request对象以及回调函数等信息) + 当前的去重队列(存放访问过的url地址) 实现分布式的关键就是需要找一台专门的主 ...
- selenium基础(生成测试报告)
测试报告 生成HTML测试报告 下载HTMLTestRunner.py包 下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html 下载后,把H ...
- soj97 旅行
题意:给你一棵n个点的树.m个操作,op 1:在点i上建立银行.op 2:询问从点x开始可以经过至少一个银行走到的点中编号第二大的点. n,m<=1e5. 标程: #include<bit ...
- Redis学习目录
目录 持续更新... Redis简介 Redis安装及基本配置 Redis持久化 Redis开发及管理实战 Redis高可用及集群 Redis多API开发
- Config程序配置文件(configSections)操作实践及代码详注
所有与配置文件相关的类:(粗体为一般情况下使用到的类,其它类功能可能在很复杂的情况下才使用到.) 1.ConfigurationManager,这个提供用于打开客户端应用程序集的Configurati ...
- Censoring【自动AC机】【水题毁我青春】【20190614】
这题简直比注水猪肉还水QAQ. 以前做过KMP的Censoring单串匹配,果断选择自动AC机w 对短串建自动AC机 长串去机子里匹配 用个栈边匹配边弹出 记得弹出一个串后把匹配点指向栈顶就ojbk ...
- Origin使用自定义函数拟合曲线函数
(2019年2月19日注:这篇文章原先发在自己github那边的博客,时间是2016年10月28日) 最近应该是六叔的物化理论作业要交了吧,很多人问我六叔的作业里面有两道题要怎么进行图像函数的拟合.综 ...
- centos7下Elasticsearch5.2.2和head 插件环境搭建
ElasticSearch是一个基于Lucene构建的开源,分布式,RESTful搜索引擎.设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便.支持通过HTTP使用JSON进行数据索引 ...
- JSON高亮格式化页面显示
高亮CSS定义: <style type="text/css"> pre {outline: 1px solid #ccc; padding: 5px; margin: ...
- 常用es6特性归纳-(一般用这些就够了)
之前做vue和react的时候,发现文档什么的最新版本都建议用es6写法,对es6友好度更高,加之现在es6也越来越普及,兼容性问题直接用babel转码就好了,特别方便,于是我开始学着用es6写代码, ...