题目链接
判断归并算法时,不能通过中间序列的前n位有序来判断当前序列进行了几次归并
例如:
n=8
原始序列:1 2 3 5 7 3 4 2
中间序列:1 2 3 5 3 7 2 4
中间序列只进行了一次归并排序,若按照前四位有序来判断则会误认为进行了两次归并排序。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int n;
cin>>n;
vector<int> v1(n),v2(n);
for(int i=0;i<n;i++) cin>>v1[i];
for(int i=0;i<n;i++) cin>>v2[i];
int i=0,j;
while(i<n-1&&v2[i]<=v2[i+1]) i++;
for(j=i+1;j<n&&v1[j]==v2[j];j++);
if(j==n){
cout<<"Insertion Sort"<<endl;
sort(v2.begin(),v2.begin()+i+2); //注意v2.begin()+i+2
}else{
cout<<"Merge Sort"<<endl;
int d=2*(i+1),k;
for(k=0;k<n-d;k+=d)
sort(v2.begin()+k,v2.begin()+k+d);
sort(v2.begin()+k,v2.end());
}
for(int k=0;k<n;k++){
if(k!=0) cout<<" ";
cout<<v2[k];
}
return 0;
}
测试点6无法通过
可以模拟每次归并过程,直到与中间序列相同(参考柳婼)
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){
int n;
cin>>n;
vector<int> v1(n),v2(n);
for(int i=0;i<n;i++) cin>>v1[i];
for(int i=0;i<n;i++) cin>>v2[i];
int i=0,j;
while(i<n-1&&v2[i]<=v2[i+1]) i++;
for(j=i+1;j<n&&v1[j]==v2[j];j++);
if(j==n){
cout<<"Insertion Sort"<<endl;
sort(v1.begin(),v1.begin()+i+2); //注意v2.begin()+i+2
}else{
cout<<"Merge Sort"<<endl;
int d=1;
bool flag=true;
while(flag){ //模拟归并排序
flag=false;
for(int k=0;k<n;k++)
if(v1[k]!=v2[k]) flag=true;
d*=2;
for(int k=0;k<n/d;k++)
sort(v1.begin()+k*d,v1.begin()+(k+1)*d);
sort(v1.begin()+n/d*d,v1.end());
}
}
for(int k=0;k<n;k++){
if(k!=0) cout<<" ";
cout<<v1[k];
}
return 0;
}