暴力法能拿80%的分数:
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define ll long long
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 100000+10;
const int maxa = 1000000+10;
int a[maxn];
bool num[maxa];
int n;
int main(){
cin>>n;
rep(i,1,n){
cin>>a[i];
}
rep(i,1,n){
while(num[a[i]]){
a[i]++;
}
num[a[i]] = true;
}
rep(i,1,n){
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}
运用并查集,将升序的并且使用过的数连成一个集合,该集合的根表示下一个能够使用的数。
第三个编程大题能用如此简短的代码实现是我没想到的,代码简短,但理解其原理很重要:
//修改数组
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
using namespace std;
const int maxa = 1000000+10;
int fa[maxa];
int n;
void init(){
rep(i,1,maxa){
fa[i] = i;
}
}
int find(int x){
if(fa[x]==x){
return x;
}
return fa[x] = find(fa[x]);
}
int main(){
cin>>n;
init();
int a;
rep(i,1,n){
cin>>a;
a = find(a);
cout<<a<<" ";
fa[a] = a+1;
}
cout<<endl;
return 0;
}
这样能拿下全部分数: