小高组试卷二

题目一

输入样例

14
36
2
3
49
81
35
12
89
16
100
967217
917597
185971
43607027731

输出样例

2
2
3
7
3
5
2
89
2
2
37
571
185971
43607027731

思路:

暴力判断的时间复杂度不足以通过全部样例,但是比较简单,可以拿到一部分的分

暴力代码:

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

#define int long long

const int N = 1e6 + 10;
int p[N], k;

bool isp(int x) {
	if(x <= 1) return false;
	for(int i = 2; i <= sqrt(x); i++) {
		if(x % i == 0) return false;
	}
	return true;
}

signed main(){
	
	int t;
	cin >> t;
	
	for(int i = 1; i <= t; i++) {
		int x; 
		cin >> x;
		
		int ans = x;
		for(int j = 2; j <= x - 1; j++) {
			if(x % j == 0 && isp(j)) {
				ans = j;
				break;
			}
		}
		cout << ans << endl;
	}
	
	return 0;
} 

然后,数据最大为 1e12,如果存在质因子,那么一定小于等于 1e6,我们只需要预处理出 1e6 范围内所有质数,如果这些质数不是输入这个数的因子,那么就不存在质因子

Tips:如果实在不会,那我们可以想到,如果这个数是偶数,那么他的答案一定是 2,可以得到大约一半的分

代码:

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

#define int long long

const int N = 1e6 + 10;
int p[N], k;

bool isp(int x) {
	if(x <= 1) return false;
	for(int i = 2; i <= sqrt(x); i++) {
		if(x % i == 0) return false;
	}
	return true;
}

void init(){
	for(int i = 2; i <= N; i++){
		if(isp(i))  p[++k] = i;
	}
}

signed main(){
	
	int t;
	cin >> t;
	
	init();
	
	for(int i = 1; i <= t; i++) {
		int x; 
		cin >> x;
		
		int ans = x;
		for(int j = 1; j <= k; j++) {
			if(x % p[j] == 0) {
				ans = p[j];
				break;
			}
		}
		cout << ans << endl;
	}
	
	return 0;
} 

题目二

输入样例1

5 4
3 4 1 5 2
1 2 3 4

输出样例1

1 4 3 5 2
1 2 3 5 4
1 2 3 5 4
1 2 3 4 5

输入样例2

6 3
6 4 2 3 1 5
1 3 5

输出样例2

1 4 2 3 6 5
1 2 3 4 6 5
1 2 3 4 5 6

思路

首先我们需要知道什么是选择排序,详情移步这里

于是,对于每一个询问,我们都可以去暴力解决

暴力代码

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

const int N = 1e5 + 10;

int a[N], pos[N];
int q[N], b[N];
int n, m;

void fun(int x, int y) {
	for(int i = 1; i <= n; i++) b[i] = a[i];
	
	for(int i = x; i <= y; i++) {
		int minn = 1e9, posi = -1;
		for(int j = i; j <= n; j++) {
			if(b[j] < minn) {
				minn = b[j];
				posi = j;
			}
		}
		swap(b[i], b[posi]);
	}
	
	for(int i = 1; i <= n; i++) cout << b[i] << " ";
	cout << endl; 
}

int main(){
	cin >> n >> m;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
	}
	
	for(int i = 1; i <= m; i++){
		cin >> q[i];
		
		fun(1, q[i]);
	}
	
	return 0;
} 

题目保证询问是递增的,那么我们没有必要去重复处理,直接从上一次处理完的数组接着处理即可,得分会比上一个代码高,但也不是满分

暴力代码二

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

const int N = 1e5 + 10;

int a[N], pos[N];
int q[N], b[N];
int n, m;

void fun(int x, int y) {
	
	for(int i = x; i <= y; i++) {
		int minn = 1e9, posi = -1;
		for(int j = i; j <= n; j++) {
			if(a[j] < minn) {
				minn = a[j];
				posi = j;
			}
		}
		swap(a[i], a[posi]);
	}
	
	for(int i = 1; i <= n; i++) cout << a[i] << " ";
	cout << endl; 
}

int main(){
	cin >> n >> m;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
	}
	
	for(int i = 1; i <= m; i++){
		cin >> q[i];
		
		fun(q[i - 1] + 1, q[i]);
	}
	
	return 0;
} 

上述代码通过分析时间复杂度可知依然不会满分,那我们要如何优化呢,我们来看这段代码

for(int j = i; j <= n; j++) {
	if(a[j] < minn) {
		minn = a[j];
		posi = j;
	}
}

它的功能是找到最小的那个数的位置,如果我们提前知道每个数的位置的话,我们就不用每次去循环查找了,所以我们可以提前将每个数的位置保存起来,用的时候直接存取即可

代码

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

const int N = 1e5 + 10;

int a[N], pos[N];
int q[N];

int main(){
	int n, m;
	cin >> n >> m;
	for(int i = 1; i <= n; i ++){
		cin >> a[i];
		pos[a[i]] = i;
	}
	
	for(int i = 1; i <= m; i++){
		cin >> q[i];
		
		for(int j = q[i - 1] + 1; j <= q[i]; j++){
			int t = a[j];
			swap(a[j], a[pos[j]]);
			pos[t] = pos[j];
		}
		
		for(int j = 1; j <= n; j++){
			cout << a[j] << " ";
		}
		cout << endl;
	}
	
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值