zoukankan      html  css  js  c++  java
  • 2019暑期集训第一周小结

    E、剪枝搜索

    特点:

    一轮搜索完成后,清空标记数组的问题

    在搜索的过程中,需要借助标记数组,来防止重复的访问。
    之前采取的方法是,通过标记为1,表示该值被访问过。
    但是这样做不适合多轮的搜索,因为每轮搜索结束后,都需要重新把标记数组清零。

    解决:每轮搜索都设置一个唯一的值(不再局限于1和0)

    标记数组的本质是通过设置不同的数字,来区分两块数据。

    一个区域里面的所有的点的答案值相同,如何赋值的问题
    1. 通过搜索该区域里面所有的点,得到一个答案。同时,根据题意,这个答案也是同区域里面其他点的答案。因此,希望采用记忆化的思想,当查询其他点时,直接输出答案。

    2. 联想到上一个问题中提到的标记数组,恰好,标记数组具有这样的特性,因为每轮搜索都相当于完成一个区域的查询,因此 通过查询该点的 标记数组所代表的值 ,来判断是否需要重新搜索。

    M题

    • 无向图

    无向图存边的数组容量开二倍的问题

    虽然题目只给出了一条边,但是因为是无向图,所以要正反处理两次,因此存边的数组容量应该开二倍。

    • 链式前向星

    B题 特殊的BFS边界条件判断

    背景

    因为题目要求玩家只要最后可以安全到达最后一列即可,设共有n列,根据题目规则,因为玩家只能走值为“.”的格,且玩家到达第n列,第n+1列,第n+2列都输出“YES”。 因此,如果不对第n+1列,第n+2列做预处理的话,前后条件就发生了冲突。

    教训

    • 注意辨别if前后的判断条件是否会有冲突。
    • 想一想地图之外的点如果也是可达点的话,是否需要与地图内的那些可达点统一格式。

    C题 构造

    题目

    有颜色分别为A B C D的四种颜色块,他们之间通过互相交融,使得每种颜色都能有特定数量的联通块。

    解题思想

    由小及大

    • 先看两个颜色之间
      • 先看两种颜色各形成一个连通块,会是类似于条形磁铁的样子,A全部在左边,B全部在右边,井水不犯河水。
      • 再看要求连通数为 2 1 ,则把一个A放到B中。
    • 发现四个颜色的组合,其实也可以用这种思想。

    D题 数学、构造

    • 通过点或边的个数,计算平行四边形的个数。
    • 通过平行四边形的定义,判断怎样搜索可以查询平行四边形的所有组合方式。

    这段时间做搜索做的,光想着怎么搜索来找到全部平行四边形的个数,忘记了可以直接用数学方法来计算。

    H题 DP之维护最长距离

    发现问题的关键,即一个点删除的条件是 到达该点的最长距离是否大于该点的权值,因此应当维护这么一个数组con,con[i]代表到达点i的最长路径的长度。

    k叉树 已知结点个数,判断树的深度

    
    //树型结构,已知结点数求完全k叉树的深度
    
    
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<deque>
    #include<map>
    #include<vector>
    #include<iostream>
    using namespace std;
    typedef long long  LL;
    const double pi=acos(-1.0);
    const double e=exp(1);
    //const int MAXN =2e5+10;
    const int N =332748118;
    
    int main()
    {
        LL i,p,j,n,t,k;
        LL deep,head,mid,live,two,ans,ceng;
        double ce;
        scanf("%lld",&t);
        while(t--)
        {
            scanf("%lld%lld",&k,&n);
            if(k == 2 && n == 1)
            {
                ans = 0;
            }
            else
            {
                head = 1;
                mid = 1;
                for(i = 0; i <= 100000; i++)
                {
                    ceng = i + 1;  //当前的层数
                    if(head == n)        // ceng层的满k叉树
                    {
                        ans = i * 2;
                        break;
                    }
                    else if(head > n)   //  ceng-1层满的k叉树
                    {
                        //live = i;
                        //deep = i - 1;
    
                        //  cout << " ** " << mid << "   ceng :" << ceng << endl;
                        //  cout << " head: " << head << endl;
                        // head - n 少的结点数   判断少于一半
                        if( mid - (head - n)  >  (mid / k) )                // head 当前ceng满k叉树应该有的总结点数
                        {
                            // mid 当前ceng应该有的结点数
                            ans = i * 2;
                        }
                        else
                        {
                            ans = (i - 1) * 2 + 1;
                        }
    
                        break;
                    }
    
                    mid *= k;    // k的ceng次幂
                    head += mid;
                }
            }
    
            printf("%lld
    ",ans);
    
        }
        return 0;
    }
    
    
  • 相关阅读:
    [Windows] 一些简单的CMD命令
    开发过程中用到的触发器
    MyEclipse8.5配置struts等框架
    Java编程中中文乱码问题的研究及解决方案
    开源的SSH框架优缺点分析
    java 合并排序算法、冒泡排序算法、选择排序算法、插入排序算法、快速排序
    html,CSS文字大小单位px、em、pt的关系换算
    HTML常用标签参考学习
    匹配中文字符的正则表达式
    Oracle 取上周一到周末的sql
  • 原文地址:https://www.cnblogs.com/daybreaking/p/12782822.html
Copyright © 2011-2022 走看看