一道交互练习题

题意


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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值