首页 > 其他分享 >CSP-J2022

CSP-J2022

时间:2022-11-18 22:22:20浏览次数:43  
标签:return int mid long J2022 tot CSP dp

D 整活导致 \(400\) 变 \(390\) 哭。

A. 乘方

其实枚举就能过,特判 \(a=1\) 就行了。

但是考场上看这题太像快速幂了就码了个快速幂。
普通的快速幂:

(long long)
tot=1;
while(b){
	if(b&1){
		tot*=a;
	}
	b>>=1;
	a*=a;
}

我们发现其实有 \(2\) 个地方需要判断:

  1. tot*=a,跳过不解释。
  2. a,若 while 未终止说明后面还要乘 \(a^x(x\ge1)\) 次方,若 \(a\) 已经 \(>lim\),则一定会超。
#include<bits/stdc++.h>
using namespace std;
const long long lim=1000000000;
int main(){
	long long a,b;
	scanf("%lld%lld",&a,&b);
	long long tot=1;
	while(b){
		if(a>lim){
			printf("-1");
			return 0;
		}
		if(b&1){
			tot*=a;
			if(tot>lim){
				printf("-1");
				return 0;
			}
		}
		b>>=1;
		a*=a;
	}
	printf("%lld",tot);
	return 0;
}

B. 解密

可以发现 \(e\times d=pq-p-q+2\)。
所以 \(m=n-e\times d+2=p+q\le 10^9\)。

小学数学可得:和相同,两数越相近乘积越大。
于是发现具有单调性采用二分。

#include<bits/stdc++.h>
using namespace std;
const long long lim=1000000000;
void work(long long n,long long m){
	long long l=0,r=m>>1;
	while(l<=r){
		long long mid=l+((r-l)>>1);
		if(mid*(m-mid)==n){
			printf("%lld %lld\n",mid,m-mid);
			return ;
		}
		else if(mid*(m-mid)<n){
			l=mid+1;
		}
		else{
			r=mid-1;
		}
	}
	printf("NO\n");
	return ;
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		long long n,e,d;
		scanf("%lld%lld%lld",&n,&e,&d);
		work(n,n-e*d+2);
	}
	return 0;
}

C. 逻辑表达式

感觉还是挺水的?

首先我们可以模拟建表达式树,即给定区间 \([l,r]\),找到区间内优先级最低的符号所处的位置 \(mid\),分成 \([l,mid-1]\) 和 \([mid+1,r]\) 去解决。

但是找优先级最低的是个瓶颈,我们发现可以预处理每个点其前面最靠后的 |& 为 \(lor_i,land_i\)。

我们可以先处理好其层级,即每一个括号就给他分出来一层。用桶记录最靠后的 |& 位置即可。

#include<bits/stdc++.h>
using namespace std;
const int S=1000010;
char s[S];
int ce[S],lpai[S],lor[S],land[S],t[S];
int build(int l,int r,int &tor,int &tand){
	while(lpai[r]==l){
		r--;
		l++;
	}//去掉外围括号
	if(l==r&&isdigit(s[l])){
		return s[l]-'0';
	}//单个数字
	int opt=2,w=0;
	if(lor[r]>=l){
		opt=1;
		w=lor[r];
	}//|优先级偏低
	else{
		opt=0;
		w=land[r];
	}
	int lsum=build(l,w-1,tor,tand);
	if(lsum&&opt){
		tor++;
		return 1;
	}
	if((!lsum)&&(!opt)){
		tand++;
		return 0;
	}
	int rsum=build(w+1,r,tor,tand);
	if(opt){
		return lsum|rsum;
	}
	return lsum&rsum;
}
int main(){
	scanf("%s",s+1);
	int len=strlen(s+1);
	int tp=0;
	for(int i=1;i<=len;i++){
		if(s[i]=='('){
			t[++tp]=i;
		}
		else if(s[i]==')'){
			lpai[i]=t[tp--];
		}
		ce[i]=tp;//层级
	}
	for(int i=0;i<=len;i++){
		t[i]=0;
	}
	for(int i=1;i<=len;i++){
		if(s[i]=='|'){
			t[ce[i]]=i;
		}
		lor[i]=t[ce[i]];
	}
	for(int i=0;i<=len;i++){
		t[i]=0;
	}
	for(int i=1;i<=len;i++){
		if(s[i]=='&'){
			t[ce[i]]=i;
		}
		land[i]=t[ce[i]];
	}
	int tor=0,tand=0;
	printf("%d\n",build(1,len,tor,tand));
	printf("%d %d",tand,tor);
	return 0;
}

D. 上升点列

考虑 DP,设 \(dp_{i,k}\) 为第 \(i\) 个点为终点一共串联起来 \(k\) 个固定的点所需要的点数最小值。

\(dp_{i,k}=\min\{dp_{j,k-1}+(x_i+y_i-x_j-y_j)\}(i\not=j,x_i\ge x_j,y_i\ge y_j)\)。

\(O(n^3)\) 可过。

#include<bits/stdc++.h>
using namespace std;
const int N=510;
int x[N],y[N],dp[N][N];
int main(){
	int n,t;
	scanf("%d%d",&n,&t);
	for(int i=1;i<=n;i++){
		scanf("%d%d",&x[i],&y[i]);
		dp[i][1]=0;
	}
	for(int k=2;k<=n;k++){
		for(int i=1;i<=n;i++){
			dp[i][k]=INT_MAX;
			for(int j=1;j<=n;j++){
				if(i==j||dp[j][k-1]==INT_MAX){
					continue;
				}
				if(x[i]<x[j]||y[i]<y[j]){
					continue;
				}
				int dis=x[i]+y[i]-x[j]-y[j]-1;
				if(dp[j][k-1]+dis>t){
					continue;
				}
				dp[i][k]=min(dp[i][k],dp[j][k-1]+dis);
			}
		}
	}
	for(int k=n;k>=1;k--){
		for(int i=1;i<=n;i++){
			if(dp[i][k]!=INT_MAX){
				printf("%d",t+k);
				return 0;
			}
		}
	}
	return 0;
}

标签:return,int,mid,long,J2022,tot,CSP,dp
From: https://www.cnblogs.com/lhzawa/p/16905050.html

相关文章

  • CSP 202206-1 归一化处理 C++
    1#include<iostream>2#include<vector>3#include<math.h>45intmain(){6intx{},sum{};7std::cin>>x;8std::vector<int>n(x,0);......
  • CSP 201403-1 相反数 C++
    1#include<iostream>2#include<vector>3#include<algorithm>45intmain(){6intx{},sum{};7std::cin>>x;8std::vector<int>n(......
  • CSP 201312-2 ISBN号码 C++
     1#include<iostream>2#include<algorithm>4#include<array>56intmain(){7std::array<int,9>ISBN{};8charc{};9intlenth{......
  • CSP-J 逻辑表达式
    对于a&b这种形式,如果是0&,则b的值不重要,发生依次短路,新的额结构体的短路次数=a的短路次数+1如果是1&,新的结构体的短路次数=a和b的短路次数之和,把新的结构体压入栈中#incl......
  • P8816 [CSP-J 2022] 上升点列 题解
    题目传送门:luoguP8816[CSP-J2022]上升点列这是一道简单的dp题。定义到达指两点的曼哈顿距离是\(1\)。我们考虑设状态\(f(i,j)\)表示考虑结尾是第\(i\)个点,增......
  • CSP-S退役记2
    今天三调,不过和我们没有关系,毕竟也不参考。终于可以考一次年级倒第一了。中午403的化奥大佬说我们宿舍被通报没有值日,苗要在考完试后停他们两位的课,他觉得停不了我们的课......
  • CSP-S退役记3
    中午全体去吃火锅,谁知道以后还会不会有呢?这好像是第一次在12:40的铃声之后回到宿舍的吧。下午开会前做核酸,偌大的大厅只有我们信奥,在那里等待的四五名蓝衣医务人员,问虎哥......
  • CSP-S游记
    今天出发去石家庄,大家都很开心,于是在上午考完了学长出的三道IOI题后,大多改完T1就开始颓了。不久后,虎哥通过对讲机说,陶主任让smtwy在1:45其他学生起床后,带两个人去宿舍扫厕......
  • CSP-S初赛退役记
    下午13:55到考场下候场,约十几分钟后进场,之后处理特别像写轮眼的录屏软件,发每个人的考号和密码,进网站。开考第一件事干什么?登录。第二件呢?睡觉!发下来的网址登不上去,一直显......
  • CSP-S退役记0
    自从我第一次有意识以来,眼前是一个昏暗的道路,路上敌军挡道,数量众多,我听到一道声音,“这些对她来说,不过是螳臂当车罢了”,果然,身为那为女主人公,一袭白衣,手持长刀,眼前的敌人也......