UASCO 1.3 wormholes

来源:互联网 发布:红包尾数软件 编辑:程序博客网 时间:2024/06/05 20:07

解题思路
通过回溯求出所有组合,然后枚举每个入口进入后是否进入死循环;

解题步骤
1. 将虫洞排序(先按y坐标排, y坐标相同相同再排x坐标);

bool cmp(map c,map v){    if(c.y==v.y)    return c.x<v.x;    return c.y<v.y;}

2.记录每个点t沿x轴方向右边最近的点,保存在next[t]中,若右边没有点,则next[t]=0(由于这里排过序了,所以可以线性查找);

for( int  i=1 ; i<n ; i++ ){    if(p[i].y<p[i+1].y;    next[i]=i+1;}

3.回溯,求出n个数两两配对的所有组合,用数组a存,单双成对;
考虑到不能重复(比如12 34和12 43和34 12)这里的限制条件是:偶数位cs一定大于他的前一位cs-1,奇数位一定大于他的前面第二位cs-2;
cs>n时得到一组解

void hs(int cs){    if(cs>n)    {            for(int i=1;i<n;i+=2)        {            partner[a[i]]=a[i+1];            partner[a[i+1]]=a[i];        }        sum+=pd();        return;    }    if(cs%2!=0)    {        if(cs>1)        {        for(int i=a[cs-2];i<=n;i++)        {            if(book[i]==0)            {                book[i]=1;                a[cs]=i;                hs(cs+1);                book[i]=0;            }         }        return;        }        for(int i=1;i<=n;i++)        {            if(book[i]==0)            {                book[i]=1;                a[cs]=i;                hs(cs+1);                book[i]=0;            }         }        return ;     }    if(cs%2==0)    {        for(int i=a[cs-1]+1;i<=n;i++)        {            if(book[i]==0)            {            book[i]=1;            a[cs]=i;        }ok[i]=0;    }        }        return;

4.每得到一组解,进行判断:从每个点进去,模拟运动情况,判断是否会进入死循环;

int pd(){    int flag=0;    for(int i=1;i<=n;i++)    {        memset(book2,0,sizeof(book2));              flag=enter(i);        if(flag==1)return 1;    }     return 0;}

5.模拟从每个点进去的结果,不会循环返回0,会循环返回1;

int enter(int po){    int t=po;    int now=1;    while(1)    {        if(now==1)        {            book2[t]=1;            t=partner[t];            now=0;        }        if(now==0)        {            if(next[t]==0)                return 0;            t=next[t];            if(book2[t]==1)                return 1;            book2[t]=1;            now=1;        }    }}
0 0
原创粉丝点击