『模拟赛』CSP-S模拟9

Rank

烂,知耻而后勇

image

A. 邻面合并

签。

注意到列数 \(m\le 8\),我们可以直接先搜出每一行可能的“分块”情况,然后转移时枚举上一行的所有状态和这一行的所有状态,根据拼接情况来更新答案,最终答案即为 \(n\) 行所有情况的最小值。

赛时开始打的错解,错解如果第一行总数计算错了就能过小样例(?),然后就改错了,后来打了正解,没改回来能过大样例,而且不是很会打这一题的暴力就没写拍,故挂 30pts。

由于状态那不太会表示,所以存状态用了 vector<vector<int> >,可能不是最优的。

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{char ch = getchar();lx x = 0 , f = 1;for(;ch<'0'||ch>'9';ch = getchar()) if(ch == '-') f = -1;for(;ch>= '0' && ch<= '9';ch = getchar()) x = (x<<3) + (x<<1) + (ch^48);return x*f;
}
#undef lx
#define qr qr()
#define pii pair<int , int>
#define fi first
#define se second
const int Ratio = 0;
const int N = 100 + 5;
int n, m, ans = 1e9;
int d[N][N], zt[N], zc[N];
vector<vector<int> > v[N];
vector<int> f[N];
bool yz[N];
namespace Wisadel
{void Wdfs(int hang, int x){if(x > m){vector<int> cz;fo(i, 1, m){cz.push_back(zc[i]);}v[hang].push_back(cz);return;}if(d[hang][x] == 0) zc[x] = 0, Wdfs(hang, x + 1);else{if(d[hang][x - 1] == 1) zc[x] = zc[x - 1], Wdfs(hang, x + 1);zc[x] = x, Wdfs(hang, x + 1);}}short main(){freopen("merging.in", "r", stdin) , freopen("merging.out", "w", stdout);n = qr, m = qr;fo(i, 1, n) fo(j, 1, m) d[i][j] = qr, zt[i] |= d[i][j] * (1 << (j - 1));fo(i, 1, n) Wdfs(i, 1), f[i].resize(v[i].size());fo(i, 0, v[1].size() - 1){f[1][i] = 0;int num = 0;fo(j, 0, m - 1){if(j == 0 &&v[1][i][j] != 0) num++;else if(v[1][i][j] != v[1][i][j - 1] && v[1][i][j] != 0) num++;}f[1][i] = num;}fo(i, 2, n){fo(k, 0, v[i].size() - 1){f[i][k] = 1e9;fo(j, 0, v[i - 1].size() - 1){int num = 0, las = v[i][k][0], st = 0; bool lian = 0;fo(z, 1, m - 1){if(v[i][k][z] != las && las != 0)if(v[i][k][z - 1] != v[i - 1][j][z - 1] || v[i][k][st] != v[i - 1][j][st] || v[i - 1][j][z] == las)num++;if(las != v[i][k][z]) las = v[i][k][z], st = z;if(v[i][k][z] == 0) continue;}if(v[i][k][m - 1] != 0 && (v[i][k][m - 1] != v[i - 1][j][m - 1] || v[i][k][st] != v[i - 1][j][st])) num++;f[i][k] = min(f[i][k], num + f[i - 1][j]);}}}fo(i, 0, v[n].size() - 1) ans = min(ans, f[n][i]);printf("%d\n", ans);return Ratio;}
}
int main(){return Wisadel::main();}

B. 光线追踪

由于看到区间(面)修改和单点(线)查询就一下想到了线段树,赛时思路是先离线将询问按斜率升序映射到一个序列上,由于边界等种种问题导致这样很不好实现,由于没开 long long 挂掉可以拿到的 30pts。

用线段树维护关键在想到转换成角度来做。角度范围只有 \(\left[0,\frac{\pi}{2}\right]\),每次加面相当于是对一定角度做区间推平,查询一个向量相当于是对一个角度做单点查询,理解这种转化后 这题就好说了 还是很恶心。

想到映射就该想到离散化的。考虑每次覆盖一个面对答案有影响的只有下面和左面的两条边,因此有用的三个向量即为原点指向左上、左下、右下三点的向量。我们将它们同询问的向量全部离散化,最多只会有 \(3n\) 个不同的向量,这样它们映射后的下标就形成了一个序列,我们就可以愉快地在上面进行区间修改单点查询的操作了。

不过想必 T2 不会这么容易,还有很多细节要处理。首先是修改后答案是否更改,由小样例可知存在一种这样的情况:

image

可以看到,2 虽然是后加的,但是红线范围内的答案仍是 1。

我们考虑针对横纵坐标分别开线段树维护其范围内相反坐标的最小值及其序号。简单说,就是对于横坐标的线段树,维护其范围内最小的纵坐标及其序号(答案),纵坐标相同取序号大的,对于纵坐标同理。

每次新增障碍即横坐标线段树增加长方形下边,纵坐标线段树增加长方形左边;每次询问即查询横坐标和纵坐标的线段树并取优。如何取优?首先对于横纵其中一种答案为 0 的,去另一种即可;否则因为斜率相同,我们取横坐标小的;若都相同则取序号大的即可。

实现起来细节还是挺多的,注意横坐标线段树维护的最小纵坐标和纵坐标线段树维护的最小横坐标需要开 long long,因为这个调了快一个小时。注意比较斜率用交叉相乘法,以及线段树大小开够,其它地方正常 'int' 和 'double' 就能过。

点击查看代码
#include<bits/stdc++.h>
#define fo(x, y, z) for(register int (x) = (y); (x) <= (z); (x)++)
#define fu(x, y, z) for(register int (x) = (y); (x) >= (z); (x)--)
using namespace std;
typedef long long ll;
#define lx ll
inline lx qr()
{char ch = getchar();lx x = 0 , f = 1;for(;ch<'0'||ch>'9';ch = getchar()) if(ch == '-') f = -1;for(;ch>= '0' && ch<= '9';ch = getchar()) x = (x<<3) + (x<<1) + (ch^48);return x*f;
}
#undef lx
#define qr qr()
#define pii pair<int , int>
#define fi first
#define se second
const int Ratio = 0;
const int N = 5e5 + 5;
const int mod = 998244353;
int n, tot;
double k[N << 2];
struct rmm{int op, xa, ya, xb, yb;} q[N];
struct Ans{int ans; ll minn;};
struct Wtree
{Ans t[N << 2];#define ls (rt << 1)#define rs (rt << 1 | 1)#define mid ((l + r) >> 1)void Wupd(int rt, int l, int r, int x, int y, int id, int minn){if(x <= l && r <= y){if(!t[rt].ans || (t[rt].minn >= minn))t[rt].ans = id, t[rt].minn = minn;return;}if(x <= mid) Wupd(ls, l, mid, x, y, id, minn);if(y > mid) Wupd(rs, mid + 1, r, x, y, id, minn);}Ans Wq(int rt, int l, int r, int x){if(l == r) return t[rt];Ans res;if(x <= mid) res = Wq(ls, l, mid, x);else res = Wq(rs, mid + 1, r, x);if(!t[rt].ans) return res;if(!res.ans) return t[rt];if(t[rt].minn < res.minn) return t[rt];else if(t[rt].minn == res.minn && t[rt].ans > res.ans) return t[rt];return res;}
} h, s;
namespace Wisadel
{double Wget(int x, int y){if(x == 0) return 1.0 * 1e18;return 1.0 * y / (1.0 * x);}int Wpk(Ans x, Ans y, int xx, int yy){if(!x.ans && !y.ans) return 0;if(!x.ans) return y.ans;if(!y.ans) return x.ans;if(!xx){if(q[x.ans].ya < q[y.ans].ya) return x.ans;return y.ans;}if(!yy){if(q[x.ans].xa < q[y.ans].xa) return x.ans;return y.ans;}if(x.minn * xx == y.minn * yy){if(x.ans > y.ans) return x.ans;return y.ans;}if(x.minn * xx < y.minn * yy) return x.ans;return y.ans;}short main(){freopen("raytracing.in", "r", stdin) , freopen("raytracing.out", "w", stdout);n = qr;fo(i, 1, n){q[i].op = qr, q[i].xa = qr, q[i].ya = qr;if(q[i].op == 1){q[i].xb = qr, q[i].yb = qr;k[++tot] = Wget(q[i].xa, q[i].ya);k[++tot] = Wget(q[i].xa, q[i].yb);k[++tot] = Wget(q[i].xb, q[i].ya);}else k[++tot] = Wget(q[i].xa, q[i].ya);}sort(k + 1, k + 1 + tot);tot = unique(k + 1, k + 1 + tot) - k - 1;fo(i, 1, n){if(q[i].op == 1){int zs = lower_bound(k + 1, k + 1 + tot, Wget(q[i].xa, q[i].yb)) - k,zx = lower_bound(k + 1, k + 1 + tot, Wget(q[i].xa, q[i].ya)) - k,yx = lower_bound(k + 1, k + 1 + tot, Wget(q[i].xb, q[i].ya)) - k;h.Wupd(1, 1, tot, yx, zx, i, q[i].ya);s.Wupd(1, 1, tot, zx, zs, i, q[i].xa);}else{int kk = lower_bound(k + 1, k + 1 + tot, Wget(q[i].xa, q[i].ya)) - k;Ans La = h.Wq(1, 1, tot, kk), Ca = s.Wq(1, 1, tot, kk);printf("%d\n", Wpk(La, Ca, q[i].xa, q[i].ya));}}return Ratio;}
}
signed main(){return Wisadel::main();}

C. 百鸽笼

学习题面,鸽鸽鸽。

据说是 NOI UNR 的原题。

D. 滑稽树下你和我

有点高级,不过数据很水啊,直接输出起点距离基本上全能过,得亏绑包了。

因为数组范围开小导致少拿了 15pts。

挂挂挂挂挂挂挂。

挂了 75pts,跟得的一样多。

虽然开场再次被 T1 硬控后果断选择看后面的题,结果发现甚至都不如 T1 可做,于是只得应干 2h T1,结果还因为唐错没 AC。

开场原题,梦回 T1 3100 高光时刻,然后就罚坐 20min 后换来了这套高质量模拟赛

最近挂分越来越多了,必须得重视起来了,虽然有可能是因为昨天 abc 一发罚时没吃导致的

abc 上青了,cf 打一题摆了回来改 T2。


完结撒花~

image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/809127.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VC++ 6.0的安装及使用

1. 安装 双击运行程序vc6_cn_full.exe进行安装如果需要更改安装目录,选择浏览进行安装地址的修改,否则点击下一步程序第一次启动会弹出提示框,可去掉“启动时显示提示”选项框,下一次就不会弹出该提示框2. 一个简单的demo初学者建议选择“一个空程序”去创建控制台程序选择…

2024-2025 1 20241306第二周作业总结

学期2024-2025-1 学号:20241306 《计算机基础与程序设计》第2周学习总结 作业信息这个作业属于哪个课程 <班级的链接>(如2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 <作业要求的链接>(如2024-2025-1计算机基础与程序设计第2周作业)这个作业的目标 学…

网红狗头来深圳了,上图上图

在海雅缤纷城,晚上7点开摆摊,9点结束,10月7日结束。昨天带了变焦xf18-120mm镜头。和75mm1.2f

2024-2025-1 20241407《计算机基础与程序设计》第二周学习总结

这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计这个作业要求在哪里 [2024-2025-1计算机基础与程序设计第二周作业](https://edu.cnblogs.com/campus/besti/2024-2025-1-CFAP/homework/13266)这个作业的目标 数字化 信息安全 *自学教材:计算机科学概论(第七版)第1章…

F5负载均衡系列教程十一【流量负载不均的潜在原因】

F5作为负载均衡设备,主要目的是将流量相对均衡的分发到每台服务器上(如果服务器性能相同),但是某些情况下也可能会产生负载不均的情况,导致负载不均可能的原因主要如下图所示

Visual Studio 2015 社区版安装

下载安装包 链接:https://pan.baidu.com/s/1ebHUp-rUy75-03o5edxHcg 提取码:hs0l --来自百度网盘超级会员V1的分享1、双击安装包2、如图先选自定义,然后选安装路径(英文路径)3、3-安装选项一个就够了,如图4、安装完成

怎么清除浏览器缓存?浏览器缓存清理的方法步骤是什么?

打开浏览器,点击右上角的三个点,然后选择设置按钮。 点击“隐私设置和安全性”按钮。 点击“清除浏览数据”。 选择时间范围,点击清除数据即可,这样就可以将浏览器中的浏览记录、Cookie、缓存的图片和文件清除了。 第一步 打开edge浏览器,点击右上角的三个点,选择设置。第…

[网络爬虫] Jsoup : HTML 解析工具

1 概述 简介Jsoup是一款基于Java的HTML解析器,它提供了一种简单、灵活且易于使用的API,用于从URL、文件或字符串中解析HTML文档。它可以帮助开发人员从HTML文档中提取数据、操作DOM元素、处理表单提交等。主要特点Jsoup的主要特点包括:简单易用:Jsoup提供了一系列简单的API…

F5负载均衡系列教程八【负载均衡算法详解】

#参考文档:3https://clouddocs.f5.com/training/community/f5cert/html/class1/modules/module1.html #系统上可以配置的负载均衡算法如下所示F5默认的负载均衡算法是轮询(Round Robin)负载均衡算法描述使用场景轮询(Round Robin)这是默认的负载均衡方法。轮询方法将每个新…

搜索算法合集 - By DijkstraPhoenix

搜索算法合集 By DijkstraPhoenix 深度优先搜索 (DFS) 引入如果现在有一个迷宫,如何走路径最短?方法 走迷宫最简单粗暴的方法式什么呢?当然是把所有路都走一遍啦! 如果是手动计算的话,可能会把你手指累得抽筋,但电脑不会,电脑具有强大的算力,这种暴力的事情当然是交给电…

个人知识面/技能池

虽然走得慢,但是一直在前行 知识面/技能池 电路 模拟电路微弱信号处理信号链设计1Msps采样电路设计滤波器设计无源滤波器有源滤波器光电探测电路设计电力电子逆变电路设计磁耦合谐振式无线电能传输开关电源LED恒流驱动AC/DC 设计基本电路知识电路基础知识复习跟习题册联系现代…