题目传送:

P8813 [CSP-J2022] 乘方

  • 题目描述很简单,但是数据范围很大, \(a,b \in [1,10^9]\)。

  • 方法1:一眼 long long 快速幂,可AC,但是有一个细节

  • 快速幂可能存在情况 ans 合理,ans*a 越界到 \([1,10^9]\),这个坑需要注意。

  • 方法2:细想一下 \(2^{31}>1e9\),其实直接暴力枚举就行,特判 \(a=1\)的情况。

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+10,INF=0x3f3f3f3f, M=1e9; LL fpow(LL a,LL n){
for(int i=1; i<=n && i<32; i++){
if((LL)pow(a,i)>M) return -1;
} // 提前处理
LL ans=1;
while(n){
if(n&1) ans=ans*a;
if(ans>M || a>=M) return -1;
a = a*a;
n>>=1;
}
return ans;
}
LL slove2(LL a,LL n){
if(a==1) return 1;
LL ans=1;
for(int i=1; i<=n && i<32; i++){
ans = ans*a;
if(ans > M) return -1;
}
return ans;
}
int main(){
LL a,b;
while(cin>>a>>b){
// cout<<fpow(a,b)<<endl;
cout<<slove2(a,b)<<endl;
}
fclose(stdin); fclose(stdout); return 0;
}

P8814 [CSP-J2022] 解密

  • 题意:\(p*q=n, e*d=(p-1)(q-1)+1\),已知 \(n,e,d\),求 \(p,q\)。

  • 明显可以用一元二次方程 \(O(1)\) 解

  • 一元二次方程:\(ax^2+bx+c=0\),已知 \(a,b,c\),求解 \(x\)。

  • 公式:\(\Delta=b^2-4ac\)

  • 如果 \(\Delta < 0\),则无解。

  • 如果 \(\Delta=0\),则有唯一解 \(x=\frac{-b}{2a}\)

  • 如果 \(\Delta>0\),则有两个不同的解 \(x=\frac{-b±\sqrt{\Delta}}{2a}\)

  • 推导

\[\begin{aligned}
&e*d = p*q - (p+q) + 2\\
&p + q = n-e*d+2 = m \\
&p*q = p * (m- p) = n, 结合上述方程,代入可得如下方程: \\ \\
&p^2 - m*p + n = 0 // 解此方程,求出 p \\
&\Delta = (-m)^2 - 4*1 *n = m^2 -4n \\
\\
&if(\Delta < 0) // NO 无解 \\
&else\{ \\
&\quad p = (m^2 ± \sqrt{\Delta})/2 \\
&\quad q = n/p \\
&\quad if(p > q) swap(p,q); \\
&\quad if(p*q==n \&\& p+q==m) // p q 就是答案 \\
&\quad else // NO 无解 \\
&\} \\
&\end{aligned}
\]
点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+10,INF=0x3f3f3f3f, M=1e9;
LL k,n,e,d; int main() {
// freopen("data.in", "r", stdin);
cin>>k;
for(int i=1; i<=k; i++) {
cin>>n>>e>>d;
LL m = n+2-e*d;
LL delta = m*m - 4*n;
if(delta < 0) cout<<"NO"<<endl;
else {
LL p = (m-(LL)sqrt(delta)) /2;
LL q = n/p;
// if(p > q) swap(p, q);
if(p*q==n && p+q==m) cout<<p<<" "<<q<<endl;
else cout<<"NO"<<endl;
}
}
fclose(stdin); fclose(stdout); return 0;
}
  • 上述 \(O(1)\) 的说法其实不是那么准确,可以说是 \(O(\sqrt{n})\),主要在开方的时候,其复杂度一般是和牛顿迭代法相当的,比二分要优秀。

  • sqrt() 复杂度介绍

  • 方法2:二分答案 \(p\),单次复杂度 \(O(logn)\), 可以AC

  • \(p*q=n, p+q=m\)

  • 二分性质:两个正整数的和一定,那么差越小,乘积越大。

\[\begin{aligned}
&证明:令 a+b = n, a-b = m,\\
&则 a = \frac{n+m}{2}, b=\frac{n-m}{2},\\
&a*b = \frac{(n+m)*(n-m)}{2} = \frac{n^2-m^2}{2} \\
&由于 n是固定的,所以 m越小,a*b越大。
\end{aligned}
\]

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+10,INF=0x3f3f3f3f, M=1e9;
LL k,n,e,d; int main() {
// freopen("data.in", "r", stdin);
cin>>k;
for(int i=1; i<=k; i++) {
cin>>n>>e>>d;
LL m = n+2-e*d;
LL l=1, r=m-1, p, q, flag=0;
while(l<=r) {
p = l+r>>1, q = m-p;
if(p*q==n) {
if(p>q) swap(p, q);
cout<<p<<" "<<q<<endl;
flag=1; break;
} else if(p*q<n) {
l = p+1;
} else {
r = p-1;
}
}
if(!flag) cout<<"NO"<<endl;
}
fclose(stdin); fclose(stdout); return 0;
}

P8815 [CSP-J2022] 逻辑表达式

  • 大模拟,表达式树,栈
  • 这和表达式求值的题目比较相似,只是计算对象变为三元组,确定优先级
  • 另外就是计算的一些规则需要重新推导一下,如下图

点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e6+10,INF=0x3f3f3f3f, M=1e9;
unordered_map<char,int> pr {{'&', 2}, {'|', 1}};
/*
(v,a,b) = (value, and, or) (1,a1,b1) & (v,a2,b2) = (v, a1+a2, b1+b2)
(0,a1,b1) | (v,a2,b2) = (v, a1+a2, b1+b2)
(0,a1,b1) & (v,a2,b2) = (0, a1+1, b1)
(1,a1,b1) | (v,a2,b2) = (1, a1, b1+1)
*/ struct T {
int v,a,b;
} pa,pb;
stack<T> num;
stack<char> op; void cal() {
pb=num.top(), num.pop();
pa=num.top(), num.pop();
char c = op.top(); op.pop();
int a1=pa.a, b1=pa.b, v=pb.v, a2=pb.a, b2=pb.b;
if(c=='&') {
// (0,a1,b1) & (v,a2,b2) = (0,a1+1,b1)
// (1,a1,b1) & (v,a2,b2) = (v,a1+a2,b1+b2)
if(pa.v==0) num.push({0,a1+1,b1});
else num.push({v,a1+a2,b1+b2});
} else if(c=='|') {
// (0,a1,b1) | (v,a2,b2) = (v,a1+a2,b1+b2)
// (1,a1,b1) | (v,a2,b2) = (1,a1,b1+1)
if(pa.v==0) num.push({v,a1+a2,b1+b2});
else num.push({1,a1,b1+1});
}
}
int main() {
// freopen("data.in", "r", stdin);
string s;
while(cin>>s) {
// while(num.size()) num.pop();
// while(op.size()) op.pop(); for(int i=0; i<s.size(); i++) {
char c = s[i];
if(isdigit(c)) num.push({c-'0', 0, 0});
else if(c=='(') {
op.push(c);
} else if(c==')') {
while(op.top()!='(') cal();
op.pop();
} else {
while(op.size() && op.top()!=')' &&
pr[op.top()] >= pr[c]) cal();
op.push(c);
}
}
while(op.size()) cal();
cout<<num.top().v<<endl;
cout<<num.top().a<<" "<<num.top().b<<endl;
}
fclose(stdin); fclose(stdout); return 0;
}

P8816 [CSP-J2022] 上升点列

  • 最长上升子序列,二维DP
  • 状态:\(f_{i,j}\) 表示 以第 \(i\) 个元素结尾,插入 \(j\) 个元素的最长上升序列长度。
  • 转移:\(f_{i,j}=max\{f_{i,j-d}+d+1\} ,d = x2-x1+y2-y1-1\)
  • 目标:\(ans=max\{f_{i,k}\}\)
点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=510,INF=0x3f3f3f3f;
int n,k,f[N][N],ans=0;
struct T{
int x,y;
bool operator< (const T& rhs) const{
if(x!=rhs.x) return x<rhs.x;
return y<rhs.y;
}
}g[N]; // 状态:f[i][j] 表示序列以i结尾,添加j个点序列的最大长度
// 转移:f[i][j] = max(f[i][j], f[t][j-d]+d+1)
// d = x2-x1+y2-y1-1
int main(){
cin>>n>>k; int x,y;
for(int i=1; i<=n; i++) { cin>>x>>y; g[i]={x,y}; }
sort(g+1, g+1+n);
for(int i=1; i<=n; i++){
for(int j=0; j<=k; j++){
f[i][j]=j+1;
for(int t=1; t<i; t++){ // t -> i
if(g[t].x > g[i].x || g[t].y > g[i].y) continue;
int d=g[i].x-g[t].x+g[i].y-g[t].y-1;
if(j>=d) f[i][j]=max(f[i][j], f[t][j-d]+d+1);
}
}
}
for(int i=1; i<=n; i++) ans=max(ans,f[i][k]);
cout<<ans;
fclose(stdin); fclose(stdout); return 0;
}

CSP2022 J2参考解析的更多相关文章

  1. MVC中HtmlHelper用法大全参考

    MVC中HtmlHelper用法大全参考 解析MVC中HtmlHelper控件7个大类中各个控件的主要使用方法(1) 2012-02-27 16:25 HtmlHelper类在命令System.Web ...

  2. Spring IOC 低级容器解析

    1.IOC是什么 IOC-Inversion of Control,即"控制反转",不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不 ...

  3. 解析 Qt 字库移植并能显示中文 (上篇)

    原文http://mobile.51cto.com/symbian-272552.htm 本文介绍的是Qt 字库移植并能显示中文,需要的字体库文件,一般是多个.具体移植那一个,看你使用的字库是什么了, ...

  4. C#反射与特性(九):全网最全-解析反射

    目录 1,判断类型 1.1 类和委托 1.2 值类型 1.3 接口 1.4 数组 2, 类型成员 2.1 类 2.2 委托 2.3 接口 [微信平台,此文仅授权<NCC 开源社区>订阅号发 ...

  5. KnockoutJS 3.X API 第六章 组件(5) 高级应用组件加载器

    无论何时使用组件绑定或自定义元素注入组件,Knockout都将使用一个或多个组件装载器获取该组件的模板和视图模型. 组件加载器的任务是异步提供任何给定组件名称的模板/视图模型对. 本节目录 默认组件加 ...

  6. 转:Beautiful Soup

    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时 ...

  7. 如何用OCR图文识别软件在文档里复制内容

    ABBYY FineReader 12是一款OCR图文识别软件,可从文档中复制文本.图片和表格,粘贴到其他应用程序中.无需识别整个文档(关于ABBYY FineReader识别文档的文章,请参考解析A ...

  8. Java注解实践--annotation学习三

    注解对代码的语意没有直接影响, 他们只负责提供信息给相关的程序使用. 注解永远不会改变被注解代码的含义, 但可以通过工具对被注解的代码进行特殊处理. JDK 基本Annotation 注解 说明 @O ...

  9. JavaWeb项目开发案例精粹-第3章在线考试系统-007View层

    0.login.jsp <%@ page language="java" import="java.util.*" pageEncoding=" ...

  10. Java注解实践

    Java注解实践 标签 : Java基础 注解对代码的语意没有直接影响, 他们只负责提供信息给相关的程序使用. 注解永远不会改变被注解代码的含义, 但可以通过工具对被注解的代码进行特殊处理. JDK ...

随机推荐

  1. Minio--docker部署

    拉取镜像 docker pull minio/minio 启动容器 创建文件夹 bin data config 启动脚本 docker run -p 9000:9000 -p 9001:9001 \ ...

  2. (面试题) 面试官:如何在forEach的循环里使用break

    大家都知道 js 的 forEach里是不能使用break.但是为什么不能在forEach里使用呢?在forEach里使用break 会发生什么呢? 一. 在forEach里使用break 会发生什么 ...

  3. SQL语句中索引失效的原因

    SQL语句中索引失效的情况. 总结如下: 1. 索引字段进行判空查询时.也就是对索引字段判断是否为NULL时.语句为is null 或is not null. select * from 表一 whe ...

  4. Appium获取元素坐标

    文章转自:https://www.cnblogs.com/lfr0123/p/13686769.html appium做app自动化测试过程中,有时需要获取控件元素的坐标进行滑动操作.appium中提 ...

  5. 对Frobenius 范数的理解

    Frobenius 范数是一种矩阵范数,记为 ∣ ∣ ⋅ ∣ ∣ F ||·||_F ∣∣⋅∣∣F​,定义为一个矩阵所有元素平方和的开方,即 ∣ ∣ X ∣ ∣ F = ∑ i ∑ j x i , j ...

  6. 沁恒蓝牙系列芯片USB烧录故障排查

    目录 使用USB烧录时让ISP工具能够识别芯片的操作是按住评估板上的"Download"按键,或者将PB22短接到GND,同时给板子上电.若是第一次拿到芯片,codeflash中是 ...

  7. crontal 计划任务

    crontab每分钟定时执行: */1 * * * * service mysqld restart //每隔1分钟执行一次 */10 * * * * service mysqld restart / ...

  8. Supervisor进程守护监控部署

    前言:Supervisor在百度百科上给的定义是超级用户,监管员.Supervisor是一个进程管理工具, 当进程中断的时候Supervisor能自动重新启动该进程.可以运行在各类Unix机器上,su ...

  9. python函数传参是传值还是指针

    python中,往函数传参传的是指针,并非传值. 代码说话 如果改变函数参数的值,我们来看看改变: 但是如果是传的列表这种可变数据类型呢 传列表并没有发送改变,仍然指向的是原来的地址. 这是因为传的数 ...

  10. 使用vue渲染大量数据时应该怎么优化?

    Object.freeze 适合一些 big data的业务场景.尤其是做管理后台的时候,经常会有一些超大数据量的 table,或者一个含有 n 多数据的图表,这种数据量很大的东西使用起来最明显的感受 ...