只是交换数字0和其他数来给数组排序(这个数组的每个数的值和1其索引对应)
下面有测试点1和测试点2错误的代码和错误原因分析
AC代码
# include <iostream>
# include <algorithm>
# include <vector>
# include <unordered_map>
using namespace std;
const int maxn = 100010;
int position[maxn]; // position[i] = 目前数字i在A中的索引
int cnt=0; // 交换次数
int benwei = 0; // 目前处在本位的数字的数量
// 在交换时计数(这样就不会忘了哈哈哈哈)
void MySwap(int i, int j){
swap(position[i], position[j]);
cnt++;
}
// 因为多次用到了position[i] == i,这个意思是判断当前数字i是否已经在本位上
int main()
{
int N;
scanf("%d", &N);
for(int i=0;i<N;++i){
int num;
scanf("%d", &num);
position[num] = i;
benwei += position[i] == i;
}
int i=1; // 要把i定义在外面
while(benwei < N)
{
// 找0的索引
int pos0 = position[0];
// 如果pos0==0说明0在本位,就随便找个不在本位的数字跟它交换,0又不在本位了
if(pos0 == 0)
{
for(;i<N;++i) // 不能写成for(int i=1;i<N;++i),i要定义在最外面,不这样测试点1和2会超时
if(position[i] != i){
int posi = position[i];
MySwap(0, posi);
benwei--;
break;
}
}
// 如果0不在本位,就找0所在位置的数来和0交换,这个数就归位了。
else
{
int posshould = position[pos0];
MySwap(pos0, posshould);
benwei += position[0] == 0; // 如果不在本位的0和0号位的其他数字交换了,那么0就归位了,这时就要本位数就要额外+1
benwei++;
}
}
printf("%d\n", cnt);
return 0;
}
一开始写测试点1和2错误的笨蛋代码
数组要取的足够大,不然测试点1和2出现的是段错误而不是运行超时
测试点1和2出现运行超时的原因在32和40行
要这么做的原因
晴神宝典中写的是:
利用每个移回本位的数在后续操作中不再移动的特点,从整体上定义一个变量k,用来保存目前序列中不在本位上的最小数(初始值为1),当交换过程中,出现0回归本位的情况时,总是从当前的k开始继续寻找不在本位的数,这样就能保证复杂度总是线性级别(而不是O(N^2))
其实并不是代码有问题,而是测试数据太大了,自己写的复杂度太高了,导致测试点1和2中的大数据运行过久导致超时(在考试中估计就只能有19分了)
# include <iostream>
# include <algorithm>
# include <vector>
using namespace std;
const int maxn = 10000; // 这里要足够大(100010),不然会出现段错误而不是运行超时
vector<int> A(maxn);
bool OK[maxn] = {false}; // OK[i] 表示数字i是否归位
int cnt=0;
int benwei = 0;
void MySwap(int i, int j){
swap(A[i], A[j]);
cnt++;
}
int main()
{
int N;
cin >> N;
for(int i=0;i<N;++i){
scanf("%d", &A[i]);
if(i == A[i]){
OK[i] = true;
benwei++;
}
else{
OK[i] = false;
}
}
// int k=1; // i在这里定义并初始化就不会超时了
while(benwei < N)
{
auto it = find(A.begin(), A.end(), 0);
int pos0 = it - A.begin();
if(pos0 == 0)
{
for(int k=1;k<N;++k) // 测试点1和2出现运行超时的原因i要在while外面定义并初始化为1
if(OK[k] == false){
int posk = find(A.begin(), A.end(), k) - A.begin();
MySwap(0, posk);
OK[0] = false;
benwei--;
break;
}
}
else
{
int posshould = find(A.begin(), A.end(), pos0) - A.begin();
MySwap(pos0, posshould);
if(A[0]==0){
OK[0] = true;
benwei++;
}
OK[pos0] = true;
benwei++;
}
}
printf("%d\n", cnt);
return 0;
}