CSP-j 2022解题报告(前两题)

本文解析了CSP-J2022中两道算法题:乘方和解密。乘方题要求计算a的b次方,并在结果过大时返回-1;解密题涉及数学推导,利用一元二次方程解决质因数分解问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[CSP-J 2022] 乘方

题目背景

由于众所周知的原因,官方数据现置于子任务 0,剩余的子任务为民间数据。

题目描述

小文同学刚刚接触了信息学竞赛,有一天她遇到了这样一个题:给定正整数 aaabbb,求 aba^bab 的值是多少。

aba^babbbbaaa 相乘的值,例如 232^323 即为 333222 相乘,结果为 2×2×2=82 \times 2 \times 2 = 82×2×2=8

“简单!”小文心想,同时很快就写出了一份程序,可是测试时却出现了错误。

小文很快意识到,她的程序里的变量都是 int 类型的。在大多数机器上,int 类型能表示的最大数为 231−12^{31} - 12311,因此只要计算结果超过这个数,她的程序就会出现错误。

由于小文刚刚学会编程,她担心使用 int 计算会出现问题。因此她希望你在 aba^bab 的值超过 109{10}^9109 时,输出一个 -1 进行警示,否则就输出正确的 aba^bab 的值。

然而小文还是不知道怎么实现这份程序,因此她想请你帮忙。

输入格式

输入共一行,两个正整数 a,ba, ba,b

输出格式

输出共一行,如果 aba^bab 的值不超过 109{10}^9109,则输出 aba^bab 的值,否则输出 -1

样例 #1

样例输入 #1

10 9

样例输出 #1

1000000000

样例 #2

样例输入 #2

23333 66666

样例输出 #2

-1

提示

对于 10%10 \%10% 的数据,保证 b=1b = 1b=1
对于 30%30 \%30% 的数据,保证 b≤2b \le 2b2
对于 60%60 \%60% 的数据,保证 b≤30b \le 30b30ab≤1018a^b \le {10}^{18}ab1018
对于 100%100 \%100% 的数据,保证 1≤a,b≤1091 \le a, b \le {10}^91a,b109

解题思路

通过while循环将b个a相乘即可,但是由于数据“1≤a,b≤1091 \le a, b \le {10}^91a,b109”,所以1的1e9次方会超时(虽然官方测试样例没有1),所以要特殊考虑,。

代码展示

#include <bits/stdc++.h>
using namespace std;
int main(){
	long long a,b;//记得开long long
	cin>>a>>b;
	long long ans=1;
	if(a==1)
		cout<<1<<endl;
	else{
		bool f=true;
		for(int i=1;i<=b;i++){
			ans*=a;
			if(ans>1e9){
				cout<<-1<<endl;
				f=false;
				break;
			}
		}
		if(f)
			cout<<ans<<endl;
	}
	return 0;
}

[CSP-J 2022] 解密

题目背景

由于众所周知的原因,官方数据现置于子任务 0,剩余的子任务为民间数据。

题目描述

给定一个正整数 kkk,有 kkk 次询问,每次给定三个正整数 ni,ei,din_i, e_i, d_ini,ei,di,求两个正整数 pi,qip_i, q_ipi,qi,使 ni=pi×qin_i = p_i \times q_ini=pi×qiei×di=(pi−1)(qi−1)+1e_i \times d_i = (p_i - 1)(q_i - 1) + 1ei×di=(pi1)(qi1)+1

输入格式

第一行一个正整数 kkk,表示有 kkk 次询问。

接下来 kkk 行,第 iii 行三个正整数 ni,di,ein_i, d_i, e_ini,di,ei

输出格式

输出 kkk 行,每行两个正整数 pi,qip_i, q_ipi,qi 表示答案。

为使输出统一,你应当保证 pi≤qip_i \leq q_ipiqi

如果无解,请输出 NO

样例 #1

样例输入 #1

10
770 77 5
633 1 211
545 1 499
683 3 227
858 3 257
723 37 13
572 26 11
867 17 17
829 3 263
528 4 109

样例输出 #1

2 385
NO
NO
NO
11 78
3 241
2 286
NO
NO
6 88

提示

【样例 #2】

见附件中的 decode/decode2.indecode/decode2.ans

【样例 #3】

见附件中的 decode/decode3.indecode/decode3.ans

【样例 #4】

见附件中的 decode/decode4.indecode/decode4.ans

【数据范围】

以下记 m=n−e×d+2m = n - e \times d + 2m=ne×d+2

保证对于 100%100\%100% 的数据,1≤k≤1051 \leq k \leq {10}^51k105,对于任意的 1≤i≤k1 \leq i \leq k1ik1≤ni≤10181 \leq n_i \leq {10}^{18}1ni10181≤ei×di≤10181 \leq e_i \times d_i \leq {10}^{18}1ei×di1018
1≤m≤1091 \leq m \leq {10}^91m109

测试点编号k≤k \leqkn≤n \leqnm≤m \leqm特殊性质
11110310^310310310^310310310^3103保证有解
22210310^310310310^310310310^3103
33310310^310310910^91096×1046\times 10^46×104保证有解
44410310^310310910^91096×1046\times 10^46×104
55510310^310310910^910910910^9109保证有解
66610310^310310910^910910910^9109
77710510^5105101810^{18}101810910^9109保证若有解则 p=qp=qp=q
88810510^5105101810^{18}101810910^9109保证有解
99910510^5105101810^{18}101810910^9109
10101010510^5105101810^{18}101810910^9109

解题思路(方法一)

显而易见,我们可以通过暴力打出60分

代码展示(方法一)

#include <bits/stdc++.h>
using namespace std;

unsigned long long k,n,e,d;

int main(){
	cin>>k;
	for(int i=1;i<=k;i++){
		cin>>n>>e>>d;
		unsigned long long p,q;
		bool f=false;
		for(int j=1;j*j<=n;j++){
			if(n%j==0){
				q=n/j;
				if(e*d==(j-1)*(q-1)+1){
					f=true;
					p=j;
					break;
				}
			}
		}
		if(f)
			cout<<p<<" "<<q<<endl;
		else
			cout<<"NO"<<endl;
	}
	return 0;
}

解题思路(方法二)

根据题目,我们可以推出 p+q=n−e∗d+2=m,p + q = n − e ∗ d + 2 = m,p+q=ned+2=m,所以m=p+qm=p+qm=p+q,最后转化为解x2−mx+n=0x^2-mx+n=0x2mx+n=0这个方程。

代码展示(方法二)

#include <bits/stdc++.h>
using namespace std;

long long k,n,e,d;

int main(){
	cin>>k;
	for(int i=1;i<=k;i++){
		cin>>n>>e>>d;
		long long m=n-e*d+2;
		long long f=m*m-4*n;
		if(f>=0){
			long long ff=sqrt(f);
			if(ff*ff==f&&(m-ff)%2==0){
				cout<<(m-ff)/2<<" "<<(m+ff)/2<<endl;
				continue;
			}
		}
		cout<<"NO"<<endl;
	}
	return 0;
}
### CSP-J 2022 T4 解题思路 针对CSP-J 2022年的第四题,题目涉及地图探险问题。此题的核心在于模拟转向和移动过程,并使用`vis`数组来标记已经走过的路径[^2]。 具体来说,在处理该类问题时,通常会定义方向向量用于表示上下左右四个可能的移动方向。每次读取指令后,根据当的方向调整坐标位置并检查新位置是否超出边界或已访问过。如果遇到障碍物,则应停止进并改变方向继续尝试其他可能性直到完成所有命令为止。 为了更高效地解决这个问题,可以采用如下策略: - **初始化设置**:建立一个大小适当的地图矩阵以及相应的布尔型访问标志矩阵`vis`。 - **输入解析**:逐行读入数据,提取出起点坐标、目标终点坐标以及其他必要的参数信息。 - **核心逻辑实现**: - 利用循环结构迭代执行每一步操作; - 更新当位置的同时也要同步维护好访问状态; - 特殊情况处理(如撞墙后的回退机制)。 - **结果输出**:最终判断是否到达目的地,并按照要求格式化输出相应答案。 下面给出一段Python代码作为参考实现方式之一: ```python def explore(maze, start_pos, end_pos): directions = [(0,-1), (1,0), (0,1), (-1,0)] # 定义左下右上的顺序 rows, cols = len(maze), len(maze[0]) vis = [[False]*cols for _ in range(rows)] cur_dir_idx = 0 x,y=start_pos while True: nx, ny=x+directions[cur_dir_idx][0], y+directions[cur_dir_idx][1] if not ((0<=nx<rows and 0<=ny<cols)): break elif maze[nx][ny]=='#' or vis[nx][ny]: cur_dir_idx=(cur_dir_idx+1)%4 else: x=nx y=ny vis[x][y]=True if (x,y)==end_pos: return "YES" return "NO" if __name__=='__main__': n=int(input()) maze=[input().strip() for i in range(n)] sx,sy=list(map(int,input().split())) ex,ey=list(map(int,input().split())) print(explore(maze,(sx-1,sy-1),(ex-1,ey-1))) ``` 这段程序实现了基本的功能需求,即通过给定迷宫布局、起始点与结束点的位置来进行探索旅程仿真计算,并返回是否存在一条合法路径能够成功抵达指定地点的结果字符串["YES"/"NO"]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值