吉林大学 2017年 966 第六题

ps:这个文章是 倪老弟所写 哈哈 吉大本校保博的大佬,尊重原创作者! 感谢倪老弟!
我就借用他文章刷刷访问量吧! 希望他有天在csdn上看见自己文章 别打我 ! 开玩笑啦! 大家具体咋做自己看吧。

吉林大学 2017年 966 第六题_第1张图片
昨天晚上我看到想了好久怎么做,还去找示例里的规律,大概半小时后,我肯定了,没有数字的规律。接下来的今天,我用了讨论班3个多小时想思路加上晚上3个多小时不停的调试做完了这个题,莫名的开心。
这道题的意思是2的n次方的0、1序列组成的环,环中任意N位的表达的十进制数不同。这个与gray数列完全不同,gray数列通过变换拆分加0、1就可以做到。
首先把示例环表示的十进制数写出来:0、1、2、5、3、7、6、4。接下来的内容中出现的节点都指的是十进制数字串。1是通过0(000)后面放置1得到的,4是通过6(110)后面放置0得到的。所以总结一下:每个数都只有两种后状态,一个是后面放0、一个是后面放1,即,左移一位和左移一位+再加1。也就是说,我把这道题抽象为有向图的时候,每个节点的邻居节点都只有两个。
这样,我们就可以表示所有节点的后状态。如下图所示。第一个是节点,另外两个是指向的邻居节点。(数据结构教材中的表示方法)
吉林大学 2017年 966 第六题_第2张图片
我们可以发现,不管N为几,N个0后面一定是1,(因为如果把N个0后面还放置0就马上又出现了一个0),所以这个问就等价于这样一个图,我们要找到一条路径,起始点是1,终点是0,并且这条路径上必须包含所有节点。
大体可以有三种方法:
1.暴力解法
2.用栈的各种操作和标志位,1,0两点之间路径的深搜,选出有全部节点的那条。
3.回溯法,可以用到分支限界,例如有这样一个界限:不能连续N+1个add0或add1还有不能构成N的周期,等等,都可以缩短时间复杂度。
接下来我主要按照第二种思路
每一次的压栈都要伴随着把边的visited赋为1,并且标记已经入栈;每一次的弹栈要取消已经入栈的标记并把弹出的点的边的visited赋值为0(0节点不改visited)。
先压节点1
如果有可以压入的点(不在栈里且边的visited为0),就压进去
没有可以压入的点的话 :当栈顶元素为终点时,弹出栈顶节点
当栈顶不是终点是,弹顶,并改visited
重复,直到栈中元素为空

逻辑基本上是我一点一点试出来的,这些cout也可以更好的理解,怎么弹占压站的逻辑。

代码:

#include 
#include
#include 
#include 
#include 
#include
#include"queue"
#include"stack"
#define MAX 500
using namespace std;

class Circle
{
public:
    int n;
    int bit;
    int cir[MAX];
    int add0[MAX];
    int add1[MAX];
    int visited0[MAX];
    int visited1[MAX];
    int stackState[MAX];
    int c_position = 0;
public:
  int length(char * str)
  {
    int sum=0;
    while(str[sum]!='\0')
    {
        sum++;
    }
    return sum;
  }
  int ten(string x)
  {
    int i=0;
    int sum=0;
    for(i=0;i s;
        int c_position = 0;
        s.push(start);
        stackState[start]=1;
        int top;
        int tmp;
        top=start;
        int flag=0;
        //实现类似深搜的过程
        while((!s.empty())&&(flag==0))
        {
                    if(stackState[add0[top]]==0&&visited0[top]==0)
                    {
                        s.push(add0[top]);
                        visited0[top]=1;
                        stackState[add0[top]]=1;
                        cout<<"push: "<=0;i--)
        {
            cir[i]=s.top();
            s.pop();
        }
    }
    void result()
    {
        char * bina=new char();
        int i=0;
        for(i=0;i>n;
    Circle c(n);
    c.allTrack();
    c.result();
    return 0;
}

改进意见:有更好构造图的方法会可能更好,或者不把这个题抽象为图。

N=10 :

吉林大学 2017年 966 第六题_第3张图片
用N=3的加上中间的cout好理解一些
吉林大学 2017年 966 第六题_第4张图片
吉林大学 2017年 966 第六题_第5张图片

欢迎加入吉林大学计算机软件考研群::710212002

你可能感兴趣的:(考研真题)