• 特殊排序


    特殊排序

    有一张有n个点的有向图,有(frac{n(n-1)}{2})条边,其中不存在双向边,请使用不超过10000次询问,寻找到图中的一条未规定起点和终点的halmiton的路径,即一条路径不重不漏地经过所有点,(nleq 1000)

    交互要最少询问次数的题目,显然是一道二分的题目,不存在双向边,即一个有向完全图,而二分需要对序列二分,所以不妨假设已经确定好了经过前k-1个点的路径,第1个点为终点,现在问题就变成了第k点放在路径中的哪一个位置,于是我们二分这个位置mid,含义是放在mid前,二分区间([l,r]),如果mid指向k,那么令(r=mid-1),否则令(l=mid+1)


    求证:以上操作必然找到一个位置满足条件

    证明:

    对于mid而言如果mid指向k那么令--mid,继续进行同样地判断一直到第一个点或者是存在一个点由k指向,那么这个位置就是合法的,显然必然存在这个位置。

    对于mid而言k指向mid,令++mid,一直这样操作,知道找到一个位置该点指向mid,或者到了最后一个位置,就寻找到一个合法的位置,显然必然存在这个位置。

    于是得证。


    因此我们就可以在({large nlog_2^n})次询问中得到答案,但是这是一道交互题,注意一些细节,对于vector,如果没有元素end指针是指向begin指针的,于是当向后二分未搜到合法位置,而返回最后一个位置+1来插入的,注意没有元素时会段错误,其他情况下这种做法是可行的。

    参考代码

    #define il inline
    class Solution {
    public:
    	vector<int>czf;
        vector<int> specialSort(int N) {
    		czf.push_back(1);
    		for(int i(2);i<=N;++i)
    			czf.insert(czf.begin()+dfs(0,czf.size()-1,i),i);
    		return czf;
        }
    	il int dfs(int l,int r,int x){
    		int mid;
    		while(l<=r){
    			mid=l+r>>1;
    			if(compare(czf[mid],x))l=mid+1;
    			else r=mid-1;
    		}return l;
    	}
    };
    
    

    其实还有一个很好的想法,既然是一大小比较的问题,为什么一个一个数不插入平衡树呢,下面献上我的超时代码供各位嘲笑。

    class Solution {
    public:
    	#define il inline
    	struct point{
    		int id;
    		il bool operator<(const point&a)const{
    			return compare(id,a.id);
    		}
    	};
        vector<int> specialSort(int N) {
    		set<point>S;
    		for(int i(1);i<=N;++i)S.insert((point){i});vector<int>czf;
    		for(set<point>::iterator i(S.begin());i!=S.end();++i)
    			czf.push_back(i->id);return czf;
        }
    };
    
  • 相关阅读:
    IOS 开发者账号 (team账号)
    我能否把一个开发者帐号下的app转移到另一个开发者帐号下面?
    Xcode清楚缓存、清理多余证书
    CABasiAnimation的变化属性
    CATransform3DMakeRotation注意
    绘图详解(转摘)
    iOS开发UI篇—核心动画(UIView封装动画)(转摘)
    iOS开发UI篇—核心动画(转场动画和组动画)(转摘)
    iOS开发UI篇—核心动画(关键帧动画)(转摘)
    iOS开发UI篇—核心动画(基础动画)
  • 原文地址:https://www.cnblogs.com/a1b3c7d9/p/11208533.html
Copyright © 2020-2023  润新知