• UVA 10570 Meeting with Aliens 【枚举+结论题】


    题目链接

    题意

    给一串环形序列(首尾相连),可以进行交换任意两个数的操作。问最少进行多少步这样的操作能够使得整个序列的顺序正常(即从序列中的1开始,顺时针或逆时针相邻递增)

    分析

    首先这个题有一个简单的结论,如果要通过两两交换使得一种排列变为另一种排列,最少的方式是从最左边开始扫描一遍,若当前这个数跟目标排列不一样,就把它从后面交换过来。
    那么这个题就很简单了,枚举这串序列顺序正确的所有情况(比如:12345,51234,43215等等),算出枚举出来的排列能够变成给出序列的最少操作数,记录下来求出最小值就可以了。

    AC代码

    //UVA 10570 Meeting with Aliens
    //AC 2016-07-27 19:37:04
    //Enumeration, Math Conclusion
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <cctype>
    #include <cstdlib>
    #include <cstring>
    #include <vector>
    #include <set>
    #include <string>
    #include <map>
    #include <queue>
    #include <deque>
    #include <list>
    #include <sstream>
    #include <stack>
    using namespace std;
    
    #define cls(x) memset(x,0,sizeof x)
    #define inf(x) memset(x,0x3f,sizeof x)
    #define neg(x) memset(x,-1,sizeof x)
    #define ninf(x) memset(x,0xc0,sizeof x)
    #define st0(x) memset(x,false,sizeof x)
    #define st1(x) memset(x,true,sizeof x)
    #define INF 0x3f3f3f3f
    #define lowbit(x) x&(-x)
    #define bug cout<<"here"<<endl;
    //#define debug
    
    deque<int> com;
    int org[600],now[600];
    int opos[600],pos[600];
    int n;
    
    int main()
    {
        #ifdef debug
            //freopen("E:\Documents\code\input.txt","r",stdin);
            freopen("E:\Documents\code\output1.txt","w",stdout);
        #endif
        while(cin>>n&&n)
        {
            com.clear();
            for(int i=0;i<n;++i)
            {
                com.push_back(i+1);
                cin>>org[i];
                opos[org[i]]=i;
            }
            //cout<<endl;
            int res=INF;
            for(int i=0;i<n;++i)
            {
                memcpy(now,org,sizeof(int)*n);
                memcpy(pos,opos,sizeof(int)*(n+1));
                int cnt=0;
                for(int i=0;i<n;++i)
                {
                    if(now[i]!=com[i])
                    {
                        ++cnt;
                        int tem1=now[i];
                        swap(now[i],now[pos[com[i]]]);
                        swap(pos[tem1],pos[com[i]]);
                    }
                }
                res=min(res,cnt);
                com.push_back(com.front());
                com.pop_front();
            }
            com.clear();
            for(int i=1;i<=n;++i)
                com.push_front(i);
            for(int i=0;i<n;++i)
            {
                memcpy(now,org,sizeof(int)*n);
                memcpy(pos,opos,sizeof(int)*(n+1));
                int cnt=0;
                for(int i=0;i<n;++i)
                {
                    if(now[i]!=com[i])
                    {
                        ++cnt;
                        int tem1=now[i];
                        swap(now[i],now[pos[com[i]]]);
                        swap(pos[tem1],pos[com[i]]);
                    }
                }
                res=min(res,cnt);
                com.push_front(com.back());
                com.pop_back();
            }
            cout<<res<<endl;
        }
    
        return 0;
    }
  • 相关阅读:
    阅读文献总结笔记11
    阅读文献总结笔记20
    阅读文献总结笔记13
    阅读文献总结笔记19
    阅读文献总结笔记17
    阅读文献总结笔记18
    阅读文献总结笔记15
    java图片以字符串的形式传输
    java与C#对接签名和验签
    SIP代码大全
  • 原文地址:https://www.cnblogs.com/DrCarlluo/p/6580604.html
Copyright © 2020-2023  润新知