zoukankan      html  css  js  c++  java
  • Addition Chains(加法链)

    poj 2248

    题目大意:给出一系列数的最后一个数,默认第一个数是1,求一系列数字,要求除第一个数外,其它的每个数都是前边两个数的和(可以是同一个数加上本身),求最少需要多少个数就能加到给定的数 ,输出,过程

    解决:bfs+路径记录,记录路径可以在结构体中加入当前地址,值,和从哪个扩展来的,三个数就够了。本题,最开始思考的时候,想着bfs一般都是要用到vis数组记录是否走过,以避免重复而导致陷入死循环, 但是,当用了vis数组后,新的问题来了,比如数n,有好多条路劲到达数n的,但是,如果第一个进队列下次遇到n不进队列了,会导致若最终求的是m,不一定第一个进队列的刚好是到m最短的,后来仔细想了下,其实不会重复的。因为,本题从一种状态转移的另一种状态的方式是加上之前路径上的每个点,每个都不一样,都是从不同的路径下来的,虽然最终加了之后的结果一样,不会造成死循环。由于要记录路径,不能用循环队列,就必把数组开的足够大,开始开到10000,re了,加了个0,就过了。

    #include <iostream>
    #include <cstring>
    #include <queue>
    #include <string>
    #include <cstdio>
    using namespace std;
    int n;
    struct node
    {
        int id;
        int val;
        int pre;
        node(){}
        node(int i,int v,int p):id(i),val(v),pre(p){}
    }q[100000];
    
    void print(int x)
    {
        if(x!=-1)
        {
            print(q[x].pre);
            printf("%d ",q[x].val);
        }
    }
    void bfs()
    {
        if(n==1){puts("1"); return;} 
        int front=0,rear=0;
        q[rear++]=node(0,1,-1);
        node now,next;
        while(rear!=front)    
        {
            now=q[front++];
            for(int i=now.id; i!=-1; i= q[i].pre)
            {
                int t=now.val+q[i].val;
                if(t==n){print(now.id); printf("%d\n",t); return;}
                if(t <= n )
                {
                    q[rear]=node(rear++, t, now.id);
                 }
            }
        }
    }
    int main()
    {
         while(scanf("%d",&n),n)
         {
              bfs();  
         }
        system("pause");
        return 0;
    }
    

  • 相关阅读:
    Katalon系列十九:元素相同或无法定位时的定位技巧
    Katalon系列十八:用例变量&用例间调用
    读《单核工作法》
    Redis 的主从同步(复制)
    Yii2 框架整体结构
    redis 是如何做持久化的
    php yii 查看帮助时会调用具体脚本类的析构函数
    Redis 底层数据结构介绍
    Redis 的常用命令
    Yii2 框架跑脚本时内存泄漏问题分析
  • 原文地址:https://www.cnblogs.com/hpustudent/p/2180808.html
Copyright © 2011-2022 走看看