• ZOJ 4103 浙江省第16届大学生程序设计竞赛 D题 Traveler 构造


    这个题,正赛的时候也没有过,不过其实已经有了正确的解法,可惜时间不多了,就没有去尝试。

    题意是有n个点,i点能通向i-1,然后i和i*2、i*2+1互通。

    请你构造一种路径从1能走完所有点,并且不重复经过每个点。

    一开始我先考虑了有什么方法能固定地走完所有点。

    然后发现 1-(2)-(4)-3-(6)-5-(10)....()为跳跃

    仅当走完了之前的所有点时才跳跃,跳跃完后再回退走完所有点。

    这样走的话,是可以走完所有点的。

    但是这样的限制是,我们只能在n=1/2/4/6/10...这些数时走完所有点,这个可行的集合可以用ai=(a(i-2)+1)*2来递推。

    换句话说,我们只要求出数列a 就可以按这个数列走出方案。

    这个题目i可以通向i*2,也可以通向i*2+1,所以我们得到了另一种移动方式ai=(a(i-2)+1)*2+1。

    这样我们能走的数就多了许多(其实是全部数都能走完 233)

    我们只要从ai=n 反向推这个数列前面的项,显然a(i-2)=ai/2-1或者(ai-1)/2-1

    而且这个其实是固定的,奇数的话想/2一定要-1,偶数反之。

    然后我们就求出了这个数列的ap ap-2 ap-4.....

    数列的其他项其实不重要 只要满足ap>ap-1即可,可以随便构造(大概)。

    以下为具体代码

    #include<bits/stdc++.h>
    using namespace std;
    int i,i0,n,m,T;
    bool vis[100005];
    stack<int>stk;
    vector<int>v;
    int main()
    {
        vis[0]=1;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            for(i=1;i<=n;i++)vis[i]=0;
            v.clear();
            while(1)
            {
                if(n<=1)break;
                stk.push(n);
                if(n%2)n=(n-1)/2-1;
                else n=n/2-1;
            }
            int now=1;
            while(1)
            {
                v.push_back(now);
                vis[now]=1;
                if(!vis[now-1])now--;
                else
                {
                    if(stk.empty())break;
                    else if(now*2==stk.top())
                    {
                        now*=2;
                        stk.pop();
                    }
                    else if(now*2+1==stk.top())
                    {
                        now=now*2+1;
                        stk.pop();
                    }
                    else
                    {
                        if(!vis[now*2])now=now*2;
                        else now=now*2+1;
                    }
                    
                }
            }
            for(i=0;i<v.size();i++)printf("%d%c",v[i],i==v.size()-1?'
    ':' ');
        }
        return 0;
    }
  • 相关阅读:
    vue seven day
    vue six day
    vue five day
    vue four day
    vue three day
    vue two day
    vue one day
    leetcode105-Golang根据前序遍历与中序遍历构建二叉树
    配置树莓派的frp反向代理与supervisor进程守护与开机自启脚本
    Golang实现二分查找算法
  • 原文地址:https://www.cnblogs.com/megalovania/p/10794215.html
Copyright © 2020-2023  润新知