UASCO 1.3 wormholes

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

解题步骤
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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值