• POJ 1033 Defragment


    根据http://hi.baidu.com/algorithm/item/d51b15f7a8ea1c0a84d278be这个开始练习ac,刚开始接触这道题时以为是道搜索题,读完之后深思了一下,感觉不需要套用一贯的dfs或者bfs,直接根据自己的思路走,然后注意一下效率问题就行了!可见算法注重灵活,而不是一贯的套用现有的模式。


    利用题中示例:

                                            簇号from[]:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
         目前簇中内容应该在的簇号to[]:0 1 2 0 7 0 5 0 0   8   3   4    0   0    0   0   0    6   0   0

    很自然的想法就是同时遍历from和to数组,如果from和to中内容相同,说明当前簇中内容不需要移动,否则为了优化必须进行移动,但是可以移动的前提是to所指的簇中内容为空,即from[to[i]]=0。可以先把满足移动条件的进行移动,由于移动之后,可能会引起其它簇满足移动条件,所以还需要再次遍历from和to,直到没有满足移动的簇。这个时候,有两种情况,一是达到优化状态,即from=to;另外一种是存在一个环,就如题中的5-7,7-5。针对第二种情况就是打破环,然后再次对满足移动条件的簇进行移动。多个嵌套循环就能解决了,但是这个过程使得需要多次遍历才能把所有满足移动条件的簇操作完全(由于移动导致了其他一些簇满足了移动条件后,需要第二次遍历才能将这些簇进行移动)。很明显会超时的。

        有没有可能使得一次遍历之后,就能把不属于环的一些簇全部移动到位呢?答案是肯定的。

       看下面代码,opt[]指在优化之后,簇i存放的是原来的opt[i]的内容。

    #include <iostream>
    #include <vector>
    using namespace std;
    int n, k;
    vector<int> opt ;
    vector<int> c2f;
    int count;
    bool moved = false;
    void MoveBeginAt(int pos)
    {
        while( opt[pos] != 0 && !c2f[pos] )
        {
    	int from = opt[pos];
    	int to = pos;
    	cout << from << " " << to << endl;
    	moved = true;
    	c2f[to] = c2f[from];
    	c2f[from] = 0;
    	opt[pos] = pos;
    	pos = from;
        }
    }
    int MaxFreeIndex()
    {
        int i = c2f.size(); 
        while( c2f[--i] );
        return i;
    }
    int main()
    {
        while( cin >> n >> k )
        {
    	opt.assign(n+1, 0);
    	c2f.assign(n+1, 0);
    	count = 0;
    	moved = false;
    	for(int i = 0; i < k; ++i)
    	{
    	    int m; cin >> m;
    	    for(int j = 0; j < m; ++j)
    	    {
    		int c; 
    		cin >> c;
    		opt[++count] = c;
    		c2f[c] = i + 1;
    	    }
    	}
    	for(int i = 1; i <= count; ++i)
    	    if( !c2f[i] )
    		MoveBeginAt( i );
    	int from = 0 ;
    	for(int i = 1; i <= count; ++i)
    	{
    	    if( opt[i] != i )
    	    {
    		if( !from )
    		    from = i;
    		else if( opt[i] == from )
    		{
    		    int to = MaxFreeIndex();
    		    cout << from << " " << to << endl;
    		    opt[i] = to;
    		    c2f[to] = c2f[from];
    		    c2f[from] = 0;
    		    MoveBeginAt( from );
    		    i = from ; 
    		    from = 0;
    		}
    	    }
    	}
    	cout << (moved?"":"No optimization needed
    ") ;
        }
        return 0;
    }
    

    另外还有一种利用栈的解法,也很巧妙,思路见 http://www.cnblogs.com/damacheng/archive/2010/09/24/1833983.html;代码实现如下:

    #include <iostream>
    #include <stack>
    #include <vector>
    using namespace std;
    int n, k;
    vector<int> opt;
    stack<int> s;
    int count ;
    int MaxFreeIndex()
    {
        int i = opt.size() - 1;
        while( opt[i] )
    	--i;
        return i;
    }
    void Work()
    {
        bool moved = false;
        for(int i = 1; i < opt.size(); ++i){
    	if( opt[i] && opt[i] != i ){
    	    moved = true;
    	    s.push( i );
    	    int b = i, cur = opt[i];
    	    while( true ){
    		s.push( cur );
    		if( !opt[cur] )
    		    break;
    		else if( opt[cur] == b ){
    		    int j = MaxFreeIndex();
    		    cout << cur << " " << j << endl;
    		    opt[j] = b;
    		    opt[cur] = 0;
    		    break;
    		}
    		cur = opt[cur];
    	    }
    	    int from, to = s.top();
    	    s.pop();
    	    while( !s.empty() ){
    		from = s.top();
    		cout << from << " " << to << endl;
    		opt[to] = opt[from];
    		to = s.top();
    		s.pop();
    	    }
    	    opt[to] = 0;
    	}
        }
        cout << (moved?"":"No optimization needed
    ") ;
    }
    int main()
    {
        while( cin >> n >> k ){
    	opt.assign( n + 1, 0 );
    	count = 0;
    	for(int i = 0; i < k; ++i){
    	    int m;
    	    cin >> m;
    	    for(int j = 0; j < m; ++j){
    		int c;
    		cin >> c;
    		opt[c] = ++count;
    	    }
    	}
    	Work();
        }
        return 0;
    }
    




  • 相关阅读:
    iOS 8 界面设计 PSD 模板(iPhone 6),免费下载
    20个华丽的时间轴例子,寻找网页设计灵感
    Hello.js – Web 服务授权的 JavaScript SDK
    Web 开发人员和设计师必读文章推荐【系列三十】
    Arctext.js
    30套免费的响应式 HTML5 & CSS3 模板下载
    Midnight.js – 实现奇妙的固定头部切换效果
    推荐20个很有帮助的 Web 前端开发教程
    SweetAlert – 替代 Alert 的漂亮的提示效果
    其实每个行业都有各自的辛苦,好的程序员并不累,他们乐此不疲(见过太多在职位事业、人生方向上随转如流的人,累了疲乏了就去做别的事情了。必须有自己的坚守和立足的点,自我驱动,否则沦为在别人的体制制度中被驱赶一生)good
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3161617.html
Copyright © 2020-2023  润新知