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

来源:互联网 发布:asp.net企业网站源码 编辑:程序博客网 时间:2024/06/06 18:56

题目链接

题意

给一串环形序列(首尾相连),可以进行交换任意两个数的操作。问最少进行多少步这样的操作能够使得整个序列的顺序正常(即从序列中的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 debugdeque<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;}
0 0