题意
O
(
n
2
)
O(n^2)
O(n2)的做法:
考虑逐位确定:对于每个位置,往后枚举有没有位置可以使得正确位置更多,如果有,那么有两种情况,1是这个位置被放到了正确的位置,2是这个位置本来应该放的数被放来了
这里的重点是我们需要区分1和2:
具体的做法是记下让这个位置答案正确位置数变大的2个位置,将其和i一起移位
这里是手绘示意图.即把p1放到i,p2放到p1,将i放到p2,然后再次询问
如果返回值和什么都不做相比变小或相等:
说明i这个位置应该放p2,p1这个位置应该放i
否则:
说明i这个位置应该放p1,p2这个位置应该放i
证明考虑讨论p1还是p2应该放在i上
#include "game.h"
using namespace std;
std :: vector<int> guess(int n, int limit) {
int vis[5005];
memset(vis,0,sizeof(vis));
std :: vector<int> ans;
ans.resize(n);
for(int i = 1; i <= n; i ++)
ans[i - 1] = i;
random_shuffle(ans.begin(),ans.end());
if(n<=9){
while(1){
if(count(ans)==n){return ans;}
next_permutation(ans.begin(),ans.end());
}
}
for(int i=0;i<n;i++){
if(vis[i])continue;
int tmp=count(ans),pos1=-1,pos2=-1;
if(tmp==n)break;
for(int j=i;j<n;j++){
if(vis[j])continue;
swap(ans[i],ans[j]);
int alfa=count(ans);
if(tmp<alfa){
if(pos1==-1)
pos1=j;
else
pos2=j;
}
swap(ans[i],ans[j]);
if(pos2!=-1)break;
}
if(pos1==-1)continue;
if(pos2==-1){
swap(ans[i],ans[pos1]);
vis[pos1]=1;
}
else{
swap(ans[i],ans[pos1]);
swap(ans[pos1],ans[pos2]);
int alfa=count(ans);
if(alfa<=tmp){
swap(ans[pos1],ans[pos2]);
swap(ans[i],ans[pos1]);
swap(ans[i],ans[pos2]);
swap(ans[pos2],ans[pos1]);
vis[pos1]=1;
}
else{
swap(ans[pos1],ans[pos2]);
swap(ans[i],ans[pos1]);
swap(ans[i],ans[pos1]);
swap(ans[pos2],ans[pos1]);
vis[pos2]=1;
}
}
}
return ans;
}