2022CSP-J线上游记
写在前面
安徽CSP取消了……
去年CSP考炸的我本来想今年一雪前耻(bushi),结果……
T1
第一题大毒瘤!
首先观察数据可以分类如下两种情况:
- \(a = 1\)
直接输出\(1\),return 0
- \(a \le 2\)
模拟乘方,由于不能超过\(10^9\),开long long
模拟就可以过。
\(Code:\)
#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
long long a, b, ans = 1;
int main()
{
freopen("pow.in","r",stdin);
freopen("pow.out","w",stdout);
cin >> a >> b;
if(a == 1) {
cout << 1;
return 0;
}
for (int i = 1; i <= b; i++) {
ans *= a;
if(ans > 1000000000) {
cout << -1;
return 0;
}
}
cout << ans;
}
T2
去年T2是大模拟题,但是我炸了……
在家写代码的时候就谨慎得多。
分析题面可知\(e \times d = pq - p - q + 2\)
\(\therefore m = n - e \times d + 2 = p + q\)
\(\therefore n = p(m - p) = mp - p^2\)
\(\therefore p^2 - mp + n = 0\)
\(\because p \leq q\)
\(\therefore p = \frac{m-\sqrt{m^2-4\times n}}{2}\)
这也就是说,这道题变成了裸的解方程!
求整数解需要有如下条件
- \(m^2 - 4 \times n\)是完全平方数
- \(m-\sqrt{m^2 - 4 \times n}\)是偶数
\(Code:\)
#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
int k;
long long n, e, d, m;
int main()
{
freopen("decode.in","r",stdin);
freopen("decode.out","w",stdout);
scanf("%d", &k);
while (k--) {
scanf("%lld%lld%lld",&n, &e, &d);
m = n - e * d + 2;
long long sqr = sqrt(m * m - 4 * n);
if(sqr * sqr != m * m - 4 * n) {
printf("NO\n");
continue;
}
if((m - sqr) % 2 == 1) {
printf("NO\n");
continue;
}
long long p = (m - sqr) / 2 , q = (m + sqr) / 2;
printf("%lld %lld\n", p, q);
}
}
T3
前置知识1:栈
前置知识2:表达式求值——中缀表达式
我们需要一个数值栈d
以及符号栈op
。
从左向右扫描表达式字符串(以本题的逻辑运算为例)
当扫到数字0
或1
时,直接加入数值栈。
当扫到符号时,分为一下三种情况:
- 是
(
直接入符号栈
- 不是括号
如果符号栈非空且符号栈栈顶的优先级大于当前符号优先级,则进行calc
运算;
否则把当前符号入栈。
- 是
)
如果符号栈栈顶不是(
,则进行calc
运算,知道栈顶是(
为止,并将(
弹出。
calc
运算步骤如下
定义ch
是符号栈栈顶符号,符号栈pop
。
定义y
是数值栈栈顶符号,数值栈pop
。
定义x
是数值栈栈顶符号,数值栈pop
。
将x
和y
执行ch
操作,并将结果压进数值栈。
扫描结束后,如果符号栈非空,则进行calc
操作至符号栈为空为止。
\(Code:\)
#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
string expr;//表达式
stack<int>d;//数值栈
stack<char>op;//符号栈
int level(char ch) { //判断符号优先级
if(ch == '&') return 2;
else if(ch == '|') return 1;
else return 0; //括号优先级最低
}
void calc() { //calc操作
int y = d.top(); d.pop();
int x = d.top(); d.pop();
char ch = op.top(); op.pop();
if(ch == '&') d.push(x & y);
else d.push(x | y);
}
int main()
{
cin >> expr;
for (int i = 0; i < expr.size(); i++) { //从左往右扫描表达式
if (expr[i] == 0 || expr[i] == 1) {
d.push(expr[i] - '0');//压入数值栈
}
else if (expr[i] == '(') op.push('(');//直接压入
else if (expr[i] != ')'){
while(!op.empty() && level(op.top()) >= level(expr[i])) calc();//运算优先级高的表达式
op.push(expr[i]);
}
else {
while(op.top() != '(') calc();//处理括号
op.pop();
}
}
while(!op.empty()) calc();//处理剩余表达式
cout << d.top();
}
前置知识3:表达树
表达式1&0|0&(0|1)
的表达树如下:
|
/ \
/ \
/ \
& |
/ \ / \
/ \ / \
1 0 0 |
/ \
/ \
0 1
我们可以看到,最早运算的运算符深度越深,且如果一个符号左边先算的式子就是该符号的左子树,右边先算的式子就是该符号的右子树,数字没有子节点。
建树过程与表达式求值类似。
\(Code:\)
#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
const int N = 1E6 + 5;
string expr;
stack<int>d, op;
int num(char ch){
if(ch == '&') return 3;
else if(ch == '|') return 2;
else if(ch == '1') return 1;
else if(ch == '0') return 0;
}
void build() {
int y = d.top();d.pop();
int x = d.top();d.pop();
int ch = op.top();op.pop();
l[ch] = x, r[ch] = y;
d.push(ch);
}
int main()
{
cin >> expr;
for (int i = 0; i < expr.size(); i++) {
dat[i + 1] = num(expr[i]);
if(expr[i] == '0' || expr[i] == '1') {
d.push(i + 1);
}
else if(expr[i] == '(') op.push(-1);
else if(expr[i] != ')'){
while(!op.empty() && dat[op.top()] >= dat[i + 1]) build();
op.push(i + 1);
}
else {
while(op.top() != -1) build();
op.pop();
}
}
while(!op.empty()) build();
}
回归本题
本题最后就是在表达树上进行\(dfs\),当左节点的表达式的值可以“垄断”右边表达式的值时,右边的就不需要进行“垄断”操作的计算。
#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
const int N = 1E6 + 5;
int l[N], r[N], dat[N], root;
int And, Or;
bool vis[N];
string expr;
stack<int>d, op;
int num(char ch){
if(ch == '&') return 3;
else if(ch == '|') return 2;
else if(ch == '1') return 1;
else if(ch == '0') return 0;
return -1;
}
void build() {
int y = d.top();d.pop();
int x = d.top();d.pop();
int ch = op.top();op.pop();
l[ch] = x, r[ch] = y;
d.push(ch);
}
int dfs(int u, int &And, int &Or) {
if(dat[u] < 2) return dat[u];
int L = dfs(l[u], And, Or);
if(dat[u] == 3 && L == 0) {
And += 1;
return 0;
}
else if(dat[u] == 2 && L == 1) {
Or += 1;
return 1;
}
int R = dfs(r[u], And, Or);
if(dat[u] == 3) return L & R;
else return L | R;
}
int main()
{
freopen("expr.in","r",stdin);
freopen("expr.out","w",stdout);
cin >> expr;
for (int i = 0; i < expr.size(); i++) {
dat[i + 1] = num(expr[i]);
if(expr[i] == '0' || expr[i] == '1') {
d.push(i + 1);
}
else if(expr[i] == '(') op.push(-1);
else if(expr[i] != ')'){
while(!op.empty() && dat[op.top()] >= dat[i + 1]) build();
op.push(i + 1);
}
else {
while(op.top() != -1) build();
op.pop();
}
}
while(!op.empty()) build();
root = d.top();
for (int i = 1; i <= expr.size(); i++) {
vis[l[i]] = vis[r[i]] = 1;
if(!l[i] && !r[i]) vis[i] = 1;
}
cout << dfs(root, And, Or) <<'\n';
cout << And << ' ' << Or;
}
T4
很明显,是\(dp\)。
首先按\(x_i\)为第一关键字,\(y_i\)为第二关键字从小到大排序。
接下来我们定义状态\(dp_{i,j}\),表示前\(i\)添加\(j\)个点后,最多能连接起多少个点,不包括后来添加的\(k\)个点。
则\(\max\{dp_{i,j}\}+k\)即为最大值,因为一定可以取完\(k\)个点。
状态转移方程:\(dp_{i,j} = \max\limits_{1\leq l \leq i}\{dp_{l,j-(x_i+y_i-x_l-y_l-1)}\}+1\)
\(Code:\)
#include<bits/stdc++.h>
#include<cstdio>
using namespace std;
int n, k, dp[505][105], ans;
struct Pos{
int x, y;
}a[505];
bool cmp(const Pos& u, const Pos& v) {
return u.x < v.x || u.x == v.x && u.y < v.y;
}
int main()
{
freopen("point.in","r",stdin);
freopen("point.out","w",stdout);
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i].x >> a[i].y;
}
stable_sort(a + 1, a + n + 1, cmp);
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= k; j++) dp[i][j] = 1;
for (int j = 1; j < i; j++) {
if(a[j].y > a[i].y) continue;
int s = a[i].x + a[i].y - a[j].x - a[j].y - 1;
for(int l = s; l <= k; l++) {
dp[i][l] = max(dp[i][l], dp[j][l - s] + 1);
}
}
ans = max(ans, dp[i][k]);
}
cout << ans + k;
}
2022CSP-J线上游记的更多相关文章
- 线上Linux服务器运维安全策略经验分享
线上Linux服务器运维安全策略经验分享 https://mp.weixin.qq.com/s?__biz=MjM5NTU2MTQwNA==&mid=402022683&idx=1&a ...
- 使用tcpcopy导入线上流量进行功能和压力测试
- 假设我们要上线一个两年内不会宕机的先进架构.在上线前,免不了单元测试,功能测试,还有使用ab,webbench等等进行压力测试. 但这些步骤非生产环境下正式用户的行为.或许你会想到灰度上线,但毕竟 ...
- 记一次线上coredump事故
1.事故背景 上周三凌晨,我负责的某个模块在多台机器上连续发生coredump,幸好发生在业务低峰期,而且该模块提供的功能也不是核心流程功能,所以对线上业务影响比较小.发生coredump后,运维收到 ...
- 转载:MySQL:亲测备份策略实例(线上真实备份案例)
是否为线上库的备份而烦恼过,这里提供一个完整的备份从属数据库的备份方案,亲测可用 说明: 备份从库,按周计,每周进行一次全备 每周一的早上六点进行全备,其他时间备份中继日志 在从库上启用rsync服务 ...
- JVM jmap dump 分析dump文件 / 如何使用Eclipse MemoryAnalyzer MAT 排查线上问题
jhat简介 jhat用来分析java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言 这个工具并不是想用于应用系统中而是用于"离线" ...
- 如何解析本地和线上XML文件获取相应的内容
一.使用Dom解析本地XML 1.本地XML文件为:test.xml <?xml version="1.0" encoding="UTF-8"?> ...
- 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 H题 Rock Paper Scissors Lizard Spock.(FFT字符串匹配)
2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...
- 2018 ACM-ICPC 中国大学生程序设计竞赛线上赛 F题 Clever King(最小割)
2018 ACM-ICPC 中国大学生程序设计竞赛线上赛:https://www.jisuanke.com/contest/1227 题目链接:https://nanti.jisuanke.com/t ...
- “玲珑杯”线上赛 Round #17 河南专场
闲来无事呆在寝室打打题,没有想到还有中奖这种操作,超开心的 玲珑杯”线上赛 Round #17 河南专场 Start Time:2017-06-24 12:00:00 End Time:2017-06 ...
- DBAplus社群线上分享----Sharding-Sphere之Proxy初探
功能 Cobar Mycat Heisenberg Shark TDDL Sharding-JDBC 是否开源 开源 开源 开源 开源 部分开源 开源 架构模型 Proxy架构 Proxy架构 Pro ...
随机推荐
- Python编程之子进程管理(subprocess)详解
引言 在写程序时,我们无法避免需要运行外部程序,相较于功能比较简单的os.system(),更加倾向于使用subprocess模块来执行外部程序. 模块介绍 subprocess.run() 使用su ...
- Period of an Infinite Binary Expansion 题解
Solution 简单写一下思考过程,比较水的数论题 第一个答案几乎已经是可以背下来的,在此不再赘述 考虑我们已经知道了\((p,q)\),其中\((p \perp q) \wedge (q \per ...
- 跨平台客户端Blazor方案尝试
一.方案选择 Electron/MAUI + Blazor(AntDesgin blazor) BlazorApp:Blazor Razor页面层,抽象独立层,被BlazorAppElectron/B ...
- 齐博x1文本代码标签的使用
文本标签虽然简单,但是使用的地方确实非常多的. {qb:tag name="XXXX" type="text"}推荐新闻{/qb:tag} 类似这种使用的频率是 ...
- .net core -利用 BsonDocumentProjectionDefinition 和Lookup 进行 join 关联 MongoDB 查询
前序 前段时间由于项目需要用到MongoDB,但是MongoDB不建议Collection join 查询,网上很多例子查询都是基于linq 进行关联查询.但是在stackoverflow找到一个例 ...
- golang中的errgroup
0.1.索引 https://waterflow.link/articles/1665239900004 1.串行执行 假如我们需要查询一个课件列表,其中有课件的信息,还有课件创建者的信息,和课件的缩 ...
- Eureka Server 实现在线扩容
Eureka Server 实现在线扩容 作者:Grey 原文地址: 博客园:Eureka Server 实现在线扩容 CSDN:Eureka Server 实现在线扩容 需求 Eureka 是 Sp ...
- 如何使用webgl(three.js)实现3D储能,3D储能站,3D智慧储能、储能柜的三维可视化解决方案——第十七课
前言 上节课我们讲了<3D光伏发电>,与之配套的就是能量存储 这节课我们主要讲讲储能,储能站,在分布式能源系统中起到调节用对电的尖峰平谷进行削峰填谷的作用.特别是小型储能站,更加灵活,因地 ...
- C#pictureBox滚轮缩放与拖拽
[转载]C#pictureBox滚轮缩放与拖拽 [转载]C#中图像平移.缩放的实现技巧 [转载]c# 通过鼠标拖动.放大图片,GDI绘图通过鼠标拖动.放大
- vulnhub靶场之VIKINGS: 1
准备: 攻击机:虚拟机kali.本机win10. 靶机:DRIPPING BLUES: 1,网段地址我这里设置的桥接,所以与本机电脑在同一网段,下载地址:https://download.vulnhu ...