题目一
输入样例
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;
}