T1 [JZOJ1235] 洪水

题目描述

  一天, 一个画家在森林里写生,突然爆发了山洪,他需要尽快返回住所中,那里是安全的。

  森林的地图由R行C列组成,空白区域用点“.”表示,洪水的区域用“*”表示,而岩石用“X”表示,另画家的住所用“D”表示,画家用“S”表示。

  有以下几点需要说明:

  1、 每一分钟画家能向四个方向移动一格(上、下、左、右)

  2、 每一分钟洪水能蔓延到四个方向的相邻格子(空白区域)

  3、 洪水和画家都不能通过岩石区域

  4、 画家不能通过洪水区域(同时也不行,即画家不能移到某个格子,该格子在画家达到的同时被洪水蔓延到了,这也是不允许的)

  5、 洪水蔓不到画家的住所

  给你森林的地图,编写程序输出最少需要花费多长时间才能从开始的位置赶回家中(如果画家不可能安全回家则输出“KAKTUS”)。

数据范围

  $2 \leq R,C \leq 50$

分析

  听说今天要加大难度,结果开局又是一道水题

  先 $BFS$ 预处理出每个区域最早被洪水蔓延的时间,再 $BFS$ 让画家把能走的路走一遍,如果能到达就输出最小步数,否则输出 $KAKTUS$

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 55 int n, m, x0, y0, x1, y1;
int t[N][N], d[N][N], vis[N][N];
int dir[][] = {, , , , , -, -, };
char g[N][N]; struct Point {
int x, y;
} p; bool check(int x, int y) {
if (x < || x > n) return false;
if (y < || y > m) return false;
if (g[x][y] == 'X') return false;
return true;
} void bfs(int x, int y) {
queue<Point> q;
t[x][y] = ;
p.x = x; p.y = y; q.push(p);
while (!q.empty()) {
Point temp = q.front(); q.pop();
for (int i = ; i < ; i++) {
int dx = temp.x + dir[i][];
int dy = temp.y + dir[i][];
if (check(dx, dy) && g[dx][dy] != 'D')
if (t[temp.x][temp.y] + < t[dx][dy]) {
t[dx][dy] = t[temp.x][temp.y] + ;
p.x = dx; p.y = dy; q.push(p);
}
}
}
} void BFS() {
queue<Point> q;
memset(d, 0x3f, sizeof d);
d[x0][y0] = ;
p.x = x0; p.y = y0; q.push(p);
while (!q.empty()) {
Point temp = q.front(); q.pop();
for (int i = ; i < ; i++) {
int dx = temp.x + dir[i][];
int dy = temp.y + dir[i][];
if (check(dx, dy) && !vis[dx][dy])
if (d[temp.x][temp.y] + < t[dx][dy]) {
d[dx][dy] = d[temp.x][temp.y] + ;
if (g[dx][dy] == 'D') return;
p.x = dx; p.y = dy; q.push(p);
vis[dx][dy] = ;
}
}
}
} int main() {
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++)
for (int j = ; j <= m; j++) {
scanf(" %c", &g[i][j]);
if (g[i][j] == 'S') x0 = i, y0 = j;
if (g[i][j] == 'D') x1 = i, y1 = j;
}
memset(t, 0x3f, sizeof t);
for (int i = ; i <= n; i++)
for (int j = ; j <= m; j++)
if (g[i][j] == '*') bfs(i, j);
BFS();
if (d[x1][y1] == inf) printf("KAKTUS\n");
else printf("%d\n", d[x1][y1]); return ;
}

T2 [JZOJ1236] 邦德I

题目描述

  每个人都知道詹姆斯邦德,著名的007,但很少有人知道很多任务都不是他亲自完成的,而是由他的堂弟们吉米邦德完成(他有很多堂弟),詹姆斯已经厌倦了把一个个任务分配给一个个吉米,他向你求助。

  每个月,詹姆斯都会收到一些任务,根据他以前执行任务的经验,他计算出了每个吉米完成每个任务的成功率,要求每个任务必须分配给不同的人去完成,每个人只能完成一个任务。

  请你编写程序找到一个分配方案使得所有任务都成功完成的最大概率。

数据范围

  $1 \leq N \leq 20$

分析

  显然状压 $DP$

  用二进制表示每种状态下已经分配了任务的人员情况,然后枚举完成第 $k$ 项任务的人($k$ 为当前状态已完成的任务),在所有前继状态中取最大值

  最后所有人分配到任务的状态得到的最大概率即为答案

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 21 int n, m, sum[ << N];
double g[N][N], f[ << N]; int main() {
scanf("%d", &n);
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++) {
scanf("%d", &m);
g[i][j] = m / 100.0;
}
f[] = ; sum[] = ;
for (int s = ; s < ( << n); s++)
for (int i = ; i <= n; i++)
if (s & ( << i - )) {
int last = s ^ ( << i - );
if (!sum[s]) sum[s] = sum[last] + ;
f[s] = max(f[s], f[last] * g[i][sum[s]]);
}
printf("%.6lf\n", f[( << n) - ] * 100.0); return ;
}

T3 [JZOJ1237] 餐桌

题目描述

  你家刚买了一套新房,想邀请朋友回来庆祝,所以需要一个很大的举行餐桌,餐桌能容纳的人数等于餐桌的周长,你想买一个能容纳最多人的餐桌,餐桌的边必须跟房间的边平行。

  输入中“.”表示空白区域,“X”表示有障碍物,餐桌所占区域必须是空白的。

  给你的房间的设计,计算最多能邀请的客人数。

数据范围

  $1 \leq R,C \leq 2 \times 10^3$

分析

  题目样例让大家看得很懵逼,原来客人数是桌子边长减去一个主人

  我们可以预处理每个点向上走最多有几块空地($f$),然后再枚举每个点作为矩形的左下角,向右扩展形成新的矩形来不断更新答案

  这是一个 $O(n^3)$ 的做法,但足以水过数据

  为了优化算法,在每一行上可以用单调栈来维护 $f$ 递增,每次加入新元素时,先计算出栈顶元素对应的答案,然后再弹出栈顶元素维护栈内单调

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 2005 int n, m, ans;
int f[N][N], s[N], l[N];
char x; int main() {
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++)
for (int j = ; j <= m; j++) {
scanf(" %c", &x);
if (x == '.') f[i][j] = f[i - ][j] + ;
}
for (int i = ; i <= n; i++) {
int top = , len;
for (int j = ; j <= m; j++) {
len = ;
while (s[top] > f[i][j] && top) {
len += l[top];
ans = max(ans, s[top] + len);
top--;
}
if (f[i][j]) {
s[++top] = f[i][j];
l[top] = len + ;
}
}
len = ;
while (top) {
len += l[top];
ans = max(ans, s[top] + len);
top--;
}
}
printf("%d\n", ans * - ); return ;
}

T4 [JZOJ1238] 自行车比赛

题目描述

  自行车赛在一个很大的地方举行,有N个镇,用1到N编号,镇与镇之间有M条单行道相连,起点设在镇1,终点设在镇2。

  两条路线只要不使用完全相同的道路就被认为是不同的,问从起点到终点一共有多少种不同的路线(如果有无穷多的路线,输出“inf”)。

数据范围

  $1 \leq N \leq 10^4$,$1 \leq M \leq 10^5$

分析

  考场上想都没想就觉得图里有环就输出 $inf$,结果挂了 $50 \, tps$

  实际上只有 $1$ 能经过环再到 $2$ 时才会有无限条路线

  然而实践证明,数据中并没有 $inf$ 的点

  听完大佬们 $Tarjan$、$DAG$、拓扑排序、莫队(雾)的讲解,感觉很强

  我发现我大概是全场最无脑的做法,而且跑得还挺快(跻身最优解第一面)

  我们分别在两个图中存入正向边和反向边

  先在正向图上 $DFS$ 标记从 $1$ 点出发可以到达的所有点,再在反向图上从 $2$ 开始 $DFS$ 查找是否存在环

  如果在图中找到了环,且环上的点已被标记,那么就说明可以从 $1$ 经过环再到达 $2$ 了

  如果不存在上述情况,则在正向图上 $DFS$(记忆化)得到每个点到 $2$ 的路线总数

  想不到吧,三个 $DFS$,竟然就 $AC$ 了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 10005
#define M 100005 int n, m, u, v, tot, tot1, ans, cir, ok, p = ;
int to[M], nxt[M], head[N], vis[N], sum[N];
int to1[M], nxt1[M], head1[N], vis1[N]; void add(int uu, int vv) {
to[++tot] = vv; nxt[tot] = head[uu]; head[uu] = tot;
to1[++tot1] = uu; nxt1[tot1] = head1[vv]; head1[vv] = tot1;
} void dfs1(int x) {
if (x == || vis[x]) return;
vis[x] = ;
for (int i = head[x]; i; i = nxt[i])
dfs1(to[i]);
} void dfs2(int x) {
if (x == ) return;
if (vis1[x] == ) {
if (vis[x]) cir = ;
return;
}
vis1[x] = ;
for (int i = head1[x]; i; i = nxt1[i]) {
if (vis1[to1[i]] != ) dfs2(to1[i]);
if (cir) return;
}
vis1[x] = ;
} int dfs(int x) {
if (x == ) return ;
if (vis[x]) return sum[x];
vis[x] = ;
for (int i = head[x]; i; i = nxt[i]) {
sum[x] += dfs(to[i]);
if (sum[x] >= p) sum[x] %= p, ok = ;
}
return sum[x];
} int main() {
scanf("%d%d", &n, &m);
for (int i = ; i <= m; i++) {
scanf("%d%d", &u, &v);
add(u, v);
}
dfs1(); dfs2();
if (cir) {printf("inf\n"); return ;}
memset(vis, , sizeof vis);
ans = dfs();
if (ok) {
int num = ; p /= ;
while (!(ans / p) && p) p /= , num++;
while (num--) printf("");
}
printf("%d\n", ans); return ;
}

2019-08-10 纪中NOIP模拟B组的更多相关文章

  1. 2019-08-21 纪中NOIP模拟A组

    T1 [JZOJ6315] 数字 题目描述

  2. 2019-08-15 纪中NOIP模拟B组

    T1 [JZOJ3455] 库特的向量 题目描述 从前在一个美好的校园里,有一只(棵)可爱的弯枝理树.她内敛而羞涩,一副弱气的样子让人一看就想好好疼爱她.仅仅在她身边,就有许多女孩子想和她BH,比如铃 ...

  3. 2019-08-25 纪中NOIP模拟A组

    T1 [JZOJ6314] Balancing Inversions 题目描述 Bessie 和 Elsie 在一个长为 2N 的布尔数组 A 上玩游戏. Bessie 的分数为 A 的前一半的逆序对 ...

  4. 2019-08-23 纪中NOIP模拟A组

    T1 [JZOJ2908] 矩阵乘法 题目描述 给你一个 N*N 的矩阵,不用算矩阵乘法,但是每次询问一个子矩形的第 K 小数. 数据范围 对于 $20\%$ 的数据,$N \leq 100$,$Q ...

  5. 2019-08-20 纪中NOIP模拟B组

    T1 [JZOJ3490] 旅游(travel) 题目描述 ztxz16如愿成为码农之后,整天的生活除了写程序还是写程序,十分苦逼.终于有一天,他意识到自己的生活太过平淡,于是决定外出旅游丰富阅历. ...

  6. 2019-08-20 纪中NOIP模拟A组

    T1 [JZOJ6310] Global warming 题目描述 给定整数 n 和 x,以及一个大小为 n 的序列 a. 你可以选择一个区间 [l,r],然后令 a[i]+=d(l<=i< ...

  7. 2019-08-09 纪中NOIP模拟B组

    T1 [JZOJ1035] 粉刷匠 题目描述 windy有N条木板需要被粉刷. 每条木板被分为M个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一 ...

  8. 2019-08-17 纪中NOIP模拟B组

    T1 [JZOJ3503] 粉刷 题目描述 鸡腿想到了一个很高(sha)明(bi)的问题,墙可以看作一个N*M的矩阵,有一些格子是有污点的.现在鸡腿可以竖着刷一次,覆盖连续的最多C列,或者横着刷一次, ...

  9. 2019-08-13 纪中NOIP模拟B组

    T1 [JZOJ1534] rank 题目描述 小h和小R正在看之前的期末&三校联考成绩,小R看完成绩之后很伤心,共有n个学生,第i个学生有一个总成绩Xi,因为他的排名是倒数第k个,于是小R想 ...

  10. 2019-08-12 纪中NOIP模拟B组

    T1 [JZOJ4879] 少女觉 题目描述 “在幽暗的地灵殿中,居住着一位少女,名为古明地觉.” “据说,从来没有人敢踏入过那座地灵殿,因为人们恐惧于觉一族拥有的能力——读心.” “掌控人心者,可控 ...

随机推荐

  1. SQL中的real、float、decimal、numeric数据类型区别

    概述: 浮点数据类型包括real型.float型.decimal型和numeric型.浮点数据类型用于存储十进制小数. 在SQL Server 中浮点数值的数据采用上舍入(Round up)的方式进行 ...

  2. .net core 3.0配置跨域

    1.ConfigureServices services.AddCors(c => { // 配置策略 c.AddPolicy("Policy", policy => ...

  3. 获取redis实例绑定cpu的情况

    redis是一个单线模型的nosql类型的数据库,而目前接触到的服务器大都是多核的,比如8c,16c,32c,64c等等.为了充分利用主机,在一台主机上必然会部署多个redis实例,默认情况cpu会随 ...

  4. #AcWing系列课程Level-2笔记——2. 归并排序算法

    归并排序算法 编写归并排序,记住下面的思路,代码也就游刃有余了! 1.首先确定数组的中间位置的分界点(下标),也就是mid=(left+right)>>1,分成left,right两段. ...

  5. spring boot 集成 Mybatis,JPA

    相对应MyBatis, JPA可能大家会比较陌生,它并不是一个框架,而是一组规范,其使用跟Hibernate 差不多,原理层面的东西就不多讲了,主要的是应用. Mybatis就不多说了,SSM这三个框 ...

  6. 吴裕雄--天生自然HADOOP操作实验学习笔记:使用hive操作hbase

    实验目的 熟悉hive和hbase的操作 熟悉hadoop.hbase.hive.zookeeper的关系 熟练大数据环境的搭建 学会分析日志排除问题 实验原理 1.hive整合hbase原理 前面大 ...

  7. git需要设置再次弹出输入账号密码

    今天在用命令行pull线上代码到本地时遇到一个尴尬的问题,因为新下载的git貌似默认了在pull,push代码时只弹出一次输入账号密码,反正我这里是这样的. 开始在pull线上代码的时候不小心密码输错 ...

  8. MySQL 8 服务器组件

    MySQL 服务器包含了一个基于组件的架构,用于扩展服务器功能.服务器和其他组件可以使用组件提供的服务.(在使用服务方面,服务器也是一个组件,等同于其他组件).组件之间交互仅通过他们各自提供的服务. ...

  9. 如何将博客搬至CSDN

    简单聊下对于博客园的印象是技术改变世界,作为一个IT技术人员很乐意把这里当作自己的网上家园,每天在这里分享着精彩的原创内容,看重的不是华丽的外表.诱人的虚名,而是纯净.专注.对技术人员的理解. CSD ...

  10. CF566C Logistical Questions(10-1)

    题意 \(n\)个点的树,有点权,有边权,\(f(x)=\sum\limits_{i=1}^n w_idis(i,x)^{1.5}\),求最小的\(f(x)\)的\(x\) 单独考虑一条链,顺序编号, ...