首页 > 其他分享 >CSP-J2022试题题解

CSP-J2022试题题解

时间:2023-05-17 23:56:58浏览次数:55  
标签:int 题解 ll long J2022 num CSP dp op

1.乘方

原题:https://www.luogu.com.cn/problem/P8813

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int XN = 1e9;
ll a,b,ans=1;
int main(){
	cin>>a>>b;
	for(int i=1;i<=b;i++){
		ans*=a;
		if(ans>XN){
			cout<<"-1";
			return 0;
		}
	}
	cout<<ans;
	return 0;
}

 

解题思路:

因为pow的速度太慢,所以要使用累乘的方法去判断

 

2.解密

原题:https://www.luogu.com.cn/problem/P8814

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll k,n,d,e;
vector<ll>vec;
pair<ll,ll>ans;
bool Solve(ll n,ll d,ll e){
	for(ll i=1;i*i<=n;i++){
		if(n%i==0){
			vec.push_back(i);
			if(n/i!=i){
				vec.push_back(n/i);
			}
		}
	}
	for(ll i=0;i<vec.size();i+=2){
		if((vec[i]-1)*(vec[i+1]-1)+1==e*d){
			ans.first=vec[i];
			ans.second=vec[i+1];
			return 1;
		}
	}
	return 0;
}
int main(){
	cin>>k;
	while(k--){
		vec=vector<ll>();
		cin>>n>>d>>e;
		if(Solve(n,d,e))cout<<ans.first<<' '<<ans.second<<'\n';
		else cout<<"NO\n";
	}
	return 0;
}

  

题解代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll k,n,e,d,m;
int main(){
	cin>>k;
	while(k--){
		cin>>n>>e>>d;
		m=n-e*d+2;
		ll l=1,r=m/2;
		while(l<r){
			ll mid=(l+r)>>1;
			if(mid*(m-mid)>=n)r=mid;
			else l=mid+1;
		}
		if(m-r>=1&&r*(m-r)==n)cout<<r<<' '<<m-r<<'\n';
		else cout<<"NO\n";
	}
	return 0;
}

  

解题思路:

计算m,使用二分确定第一个数,通过第一个数可以得出第二个数

错误原因:

想到过二分,却没有坚持自己的思路去走下去,而是选择了因数分解的方式去解题

 

3.逻辑表达式

原题:https://www.luogu.com.cn/problem/P8815

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 3e6+520;
stack<int>num;
stack<char>op;
int cnt1,cnt2,cnt=0;string s;
struct node{
	char op;
	int l,r;
}tree[N];
void creart(){
	int a=num.top();num.pop();
	int b=num.top();num.pop();
	char c=op.top();op.pop();
	if(c=='&')num.push(a&b);
	else if(c=='|')num.push(a|b);
}
void build(){
	for(int i=0;i<s.length();i++){
		if(s[i]=='(')op.push(s[i]);
		else if(s[i]==')'){
			while(op.top()!='(')creart();
			cnt--;
		}else if(s[i]=='&'){
			tree[++cnt].op='&';
			tree[cnt].l=tree[cnt].r=0;
			op.push(s[i]);
		}else if(s[i]=='|'){
			tree[++cnt].op='|';
			tree[cnt].l=tree[cnt].r=0;
			op.push(s[i]);
		}else{
			tree[++cnt].op=s[i];
			tree[cnt].l=tree[cnt].r=0;
			num.push(s[i]-'0');
		}
	}
}
int dfs(int x){
	if(tree[x].op=='0')return 0;
	if(tree[x].op=='1')return 1;
	if(tree[x].op=='&'){
		if(dfs(tree[x].l)==0){
			cnt1++;
			return 0;
		}else return dfs(tree[x].r);
	}
	if(tree[x].op=='|'){
		if(dfs(tree[x].l)==1){
			cnt2++;
			return 1;
		}else return dfs(tree[x].r);
	}
}
int main(){
	cin>>s;
	build();
	int ans=dfs(cnt);
	cout<<ans<<'\n'<<cnt1<<' '<<cnt2;
	return 0;
}

 

题解代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 3e6+520;
map<char,int>yx;
stack<int>num;
stack<char>op;
int cnt1,cnt2,cnt=0;string s;
struct node{
	char op;
	int l,r;
	node(){};
	node(char opv,int ls,int rs){
		op=opv;
		l=ls;
		r=rs;
	}
	node(char opv){
		op=opv;
	}
}tree[N];
void create(){
	int a=num.top();num.pop();
	int b=num.top();num.pop();
	char c=op.top();op.pop();
	tree[++cnt]=node(c,b,a);
	num.push(cnt);
}
void build(){
	for(int i=0;i<s.length();i++){
		if(s[i]=='(')op.push(s[i]);
		else if(s[i]==')'){
			while(op.top()!='(')create();
			op.pop();
		}else if(s[i]=='&'||s[i]=='|'){
			while(op.size()&&yx[op.top()]>=yx[s[i]])create();
			op.push(s[i]);
		}else{
			tree[++cnt]=node(s[i]);
			num.push(cnt);
		}
	}
	while(op.size())create();
}
int dfs(int x){
	if(tree[x].op=='0')return 0;
	if(tree[x].op=='1')return 1;
	if(tree[x].op=='&'){
		if(dfs(tree[x].l)==0){
			cnt1++;
			return 0;
		}else return dfs(tree[x].r);
	}
	if(dfs(tree[x].l)==1){
		cnt2++;
		return 1;
	}
	return dfs(tree[x].r);
}
int main(){
	yx['(']=0;
	yx['&']=2;
	yx['|']=1;
	cin>>s;
	build();
	
//	for(int i=1;i<=cnt;i++){
//		cout<<tree[i].op<<' '<<tree[i].l<<' '<<tree[i].r<<'\n';
//	}
	
	int ans=dfs(cnt);
	cout<<ans<<'\n'<<cnt1<<' '<<cnt2;
	return 0;
}

  

解题思路:

先读入表达式,建立表达式树,通过深搜计算每个“短路”的个数

错误原因:

建树错误,编号传递错误,导致答案错误,且没有运算符的优先级

 

4.上升点列

原题:https://www.luogu.com.cn/problem/P8816

代码:

#include<bits/stdc++.h>
#define ll long long
#define x first
#define y second
using namespace std;
const int N = 5e2+255;
pair<int,int>a[N];
int n,K,xdp[N],dp[N],ans,xn=0;
int main(){
	cin>>n>>K;
	for(int i=1;i<=n;i++)cin>>a[i].x>>a[i].y;
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++){
		int j=i+1;
		if(a[i].y>a[j].y)continue;
		xdp[j]=abs(a[j].x-a[i].x)+abs(a[j].y-a[i].y)-1;
	}
	for(int i=2;i<=n;i++)if(xdp[i])dp[++xn]=xdp[i];
	n=xn;
	for(int i=1;i<=n;i++)dp[i]+=dp[i-1];
	for(int t=1;t<=n;t++){
		for(int i=1;i<=n;i++){
			int j=i+t-1;
			if(j>n)break;
			ans=max(ans,t+(dp[j]-dp[i-1])+(K-(dp[j]-dp[i-1])));
		}
	}
	cout<<ans;
	return 0;
}

  

题解代码:

#include<bits/stdc++.h>
#define ll long long
#define x first
#define y second
using namespace std;
const int N = 5e2+255;
pair<int,int>a[N];
int n,K,dp[N][N],ans;
int main(){
	cin>>n>>K;
	for(int i=1;i<=n;i++)cin>>a[i].x>>a[i].y;
	sort(a+1,a+n+1);
	for(int i=1;i<=n;i++){
		for(int j=0;j<=K;j++){
			dp[i][j]=1;
			for(int k=1;k<i;k++){
				if(a[i].y<a[k].y)continue;
				int dis=(a[i].x-a[k].x)+(a[i].y-a[k].y)-1;
				if(j>=dis)dp[i][j]=max(dp[i][j],dp[k][j-dis]+dis+1);
			}
			ans=max(ans,dp[i][j]+K-j);
		}
	}
	cout<<ans;
	return 0;
}

  

解题思路:

输入每个点的坐标,进行排序,枚举每种组合,组成dp的数据,计算欧几里得距离,取dp的最大值即为答案

错误原因:

思路错误,原代码是前缀和,题解代码是dp算法,导致“听取WA声一片”

标签:int,题解,ll,long,J2022,num,CSP,dp,op
From: https://www.cnblogs.com/zhanghx-blogs/p/17410701.html

相关文章

  • abc270_f Transportation 题解
    Transportation题意有\(n\)个城市,你可以执行以下操作若干次:选择一个没有建机场的城市\(i\),花费\(x_i\)建一个机场。选择一个没有建港口的城市\(i\),花费\(y_i\)建一个港口。还有\(m\)条没有修建的道路,第\(i\)条道路双向连接\(a_i\)和\(b_i\),修建这条道路需要......
  • CF1077E Thematic Contests 题解
    ThematicContests题意有\(n\)个问题,每个问题有一个分类\(a_i\)。现在要举办一些比赛,要求:一场比赛中所有题目的分类相同。所有比赛的分类是互不相同的。第一场比赛的题目数量任意,但从第二场开始,每一场比赛的题目数量都必须是前一场的两倍。求所有比赛的题目数量之和的......
  • abc235_d Multiply and Rotate 题解
    MultiplyandRotate题意给定两个整数\(a\)和\(n\),有一个整数\(x\),初始值为\(1\),有两种操作:将\(x\)变成\(x\timesa\)。在\(x>10\)且\(x\)不是十的倍数的情况下可以执行此操作:将\(x\)当成一个字符串,将其循环右移一次。求最少执行多少次操作能把\(x\)变......
  • P8786 李白打酒加强版 题解
    李白打酒加强版题目大意一开始酒显里有\(2\)斗酒,每遇到一次店就会把酒显里的酒数量(单位:斗)乘\(2\),每遇到一次花就把酒显里的酒喝掉\(1\)斗。这一路上一共遇到店\(n\)次,遇到花\(m\)次,且最后一次遇到的是花,酒显里没有一斗酒了。计算这一路上遇到店和花的顺序总共有......
  • YACS 2023年5月月赛 甲组 T1 子集和(六) 题解
    YACS老师说这是道分治,但就不告诉我怎么做,我硬是用线段树卡了过去...特别解气的是把AC图片发了过去(我就是在YACS上的编程课)莫队好了说点正经的,看到是谁谁谁的倍数就能想到DP,状态设计也很水啦!设f[i]为当前考虑到的区间内,子集和%k=i的数量。新加入一个元素时,循环0~......
  • CF1183C Computer Game 题解
    ComputerGame还算水的一道题。题意本题意为题面直接翻译的简化版,可能会比题目翻译要复杂。有\(q\)次询问,每次给出四个数,表示一开始的电亮为\(k\),有\(n\)个回合,不插电玩一个回合则电量会减少\(a\),插电玩一个回合则电量会减少\(b\),电量在任何时刻都必须严格大于\(0\)......
  • Plsql或Navicat连接登陆Oracle时慢、执行语句的时候也特别慢的问题解决方案
    用Plsql或Navicat连接登陆Oracle时,等待时间特别长。经过漫长的等待后,执行语句的时候也特别慢,监听配置没毛病的情况下,大概率是监听日志文件过大导致的。监听日志路径:app\Administrator\diag\tnslsnr\LS--20171012URU\listener\trace\listener.log删除listener.log文件即可。......
  • 【Cocos2d游戏开发之九】CCSpriteBatchNode与"pvr.ccz","plist"精灵优化及注意事项
     首先对于使用过精灵的童鞋很熟悉CCSpriteBatchNode,至少大家都会知道它能优化精灵,但是至于优化原理这里简单说下:      一般使用精灵CCSprite的时候,都是直接使用[CCLayer*addChild:CCSprite*];,假设我们创建一百个精灵,那么当前的CCLayer会为100个精灵单独绘制;  ......
  • 交通运输(Wormhole Transportaion) 题解
    传送门交通运输(WormholeTransportaion)题目大意有\(n\)个点和\(m\)个点对,你需要构造一张\(m-1\)条边的无向图,使得\(m\)个点对间最短路之和最小。求最小值及取到最小值的方案数。\(2\len\le2000,2\lenm\le2\times10^7,1\leu_i,v_i\len,u_i\neqv_i\)。......
  • P3919 【模板】可持久化线段树 1(可持久化数组) 题解
    一、题目描述:维护这样的一个长度为$n$的数组,支持以下两种操作$1$:在某个历史版本上修改某一个位置上的值$2$:访问某个历史版本上的某一位置的值每进行一次操作,就会生成一个新的版本(对于操作2,生成的就是一个完全一样的版本)。版本编号即为当前操作......