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 ...
随机推荐
- Dest0g3迎新赛misc部分解析
目录 1. Pngenius 2. EasyEncode 3. 你知道js吗 4. StrangeTraffic 5. EasyWord 6.4096 7.python_jail 8. codeg ...
- SQL语句编写的练习(MySQL)
SQL语句编写的练习(MySQL) 一.建表 1.学生表(Student) 学号 | 姓名 | 性别 | 出生年月 | 所在班级 create table Student( sno varchar(2 ...
- LcdTools如何自定义读写PX01 SSD2828寄存器
LcdToos打开相应的工程文件,连接PX01并开启点亮屏使LcdTools开关处于开启状态. 切到"测试设置"栏,在"Bridge控制"栏,在"Ad ...
- SQL Server-表结构的操作
1.修改表的字段的数据类型 alter table [File_Info] alter column Upload_Request_ID nvarchar(14) not null 2.添加表的字段并 ...
- 第三方代开的微信小程序更换管理员
(1) 由于第三方代开小程序默认管理员是法人.首先使用法人微信搜索"小程序助手"小程序 (2)点击进入"小程序助手",即可看到自己企业名下未更换管理员的小程序 ...
- html中可以写php代码,但是文件后缀名需要是.php而不是.html。否则php程序不会被解析执行。
html中可以写php代码,但是文件后缀名需要是.php而不是.html.否则php程序不会被解析执行. <div class="goods_title"><?p ...
- Java多线程(6):锁与AQS(下)
您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来- 之前说过,AQS(抽象队列同步器)是Java锁机制的底层实现.既然它这么优秀,是骡子是马,就拉出来溜溜吧. 首先用重入锁来实现简单的累加,就像这 ...
- 几个实用 shell 脚本
1. Dos攻击防范(自动屏蔽攻击 IP) #!/bin/bash DATE=$(date +%d/%b/%Y:%H:%M) LOG_FILE=/usr/local/nginx/logs/demo2. ...
- 禁止eslint对指定代码检测
有时候我们引入外部文件的API时,eslint无法识别,编译的时候就会出现warn eslint是可以禁用对指定代码的检测: 单行注释 let map = new BMap.Map('map') // ...
- Git配置和使用?Git你真的会用么?Git与SVN的主要区别
1.Git环境配置 在学习Git之前,首先要知道什么是版本控制 1.1 版本控制:版本迭代.新的版本!版本管理器 版本控制是开发过程中用于管理我们的文件.目录或工程内容的修改内容,查看修改历史记 ...