第三轮测试卷一(2020.10.29)

本文详细分析了三轮测试中的编程问题,包括深度优先搜索(DFS)的应用,0-1背包问题的解决,以及最小生成树在实际中的应用。通过实例介绍了如何计算铺石板的最少数量,以及如何找到连接村庄的最低成本。同时,文章还涵盖了寻找数组中第k小数值的快速选择算法和求解二叉树高度的方法。此外,还探讨了如何反向输出单链表以及判断二叉树是否为二叉排序树的策略。
摘要由CSDN通过智能技术生成

第三轮测试卷一(2020.10.29)

试卷分析:本试卷的问题主要是:DFS还没有掌握,最小生成树和0-1背包的代码没有记住,且最小生成树不知道怎么运用到实际中去。而第5题的思路很新奇,自己需要积累。第8题自己不熟悉。

  1. 铺石板,输入n x m的广场,和a x a的石板,求最少需要多少石板?
/*
算法思想:没啥。。。。
理解向上取整就行
*/

num=((n+a-1)/a)*((m+a-1)/a);
  1. 用的0-1背包

  2. 找铺水管一共有多少种铺法?

//算法思想:DFS

#include<stdio.h>
#include<string>

int n,m;
char maze[105][105];
int vis[105][105];
int sum=0;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};

void DFS(int x,int y)
{
    if(maze[x][y]=='E')
    {
        sum++;
        return;
    }
    if(x<0||x>=n||y<0||y>=m)
        return;
    if(vis[x][y]==1)
        return;
    for(int i=0;i<4;i++)
    {
        vis[x][y]=1;
        DFS(x+dx[i],y+dy[i]);
        vis[x][y]=0;
    }
}

int main()
{
    scanf("%d %d",&n,&m);
    for(int i=0;i<n;i++)
        scanf("%s",maze[i]);
    memset(vis,0,sizeof(vis));//初始化
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<m;j++)
        {
            if(maze[i][j]=='S')
                DFS(i,j);
        }
    }
    printf("%d\n",sum);
    return 0;
}
  1. 将N个村庄连接起来(可以是间接连接),求最低成本
/*
算法思想:建立最小生成树,用Prim或者克鲁斯卡尔算法

自己的问题:不知道如何使用,对于图的算法,还有数据结构形式,不是很熟悉
*/

int getRoot(int a,int set[])
{
    while(a!=set[a])
        a=set[a];
    return a;
}

int lowcost(Road road[])//本算法返回最小花费
{
    int i;
    int a,b,min;
    int set[100];//定义并查集
    min=0;
    for(i=0;i<N;i++)
        set[i]=1;//初始化并查集,各村庄是孤立的,因此自己就是根节点
    for(i=0;i<M;i++)
    {
        /*下面这个if语句将已经有道路相连的村庄合并为一个集合*/
        if(road[i].is==1)
        {
            a=getRoot(road[i].a,set);
            b=getRoot(road[i].b,set);
            set[a]=b;
        }
    }
    /*假设函数sort()已经定义,即对road[]中的M条道路按照花费进行递增排序*/
    sort(road,M);
    /*下面这个循环从road[]数组中逐个挑出应修的道路*/
    for(i=0;i<M;i++)
    {
        if(road[i].is==0 && (a=getRoot(road[i].a,set)) != (b=getRoot(road[i].b,set)))
    /*当a,b不属于一个集合,并且a、b间没有道路时,将a、b并入同一集合,并记录下修建a、b间道路所需的花费*/
        {
            set[a]=b;
            min+=road[i].cost;
        }
    }
    return  min;//返回最小花费
}

  1. 从数组L[1…n]中找到第k小数值
/*
算法思想:在进行快速排序的过程中,每轮遍历,之后,对于枢轴元素进行判断
这种思想很新,自己要学会掌握。主要对于题目如果有要求,时间复杂度要尽可能低的时候。
*/

int kth_elem(int a[],int low,int high,int k)
{
    int pivot=a[low];
    int low_temp=low;//由于下面会修改low与high,在递归时又要用到它们
    int high_temp=high;
    while(low<high)
    {
        while(low<high&&a[high]>=pivot)
            --high;
        a[low]=a[high];
        while(low<high!!a[low]<=pivot)
            ++low;
        a[high]=a[low];
    }
    a[low]=pivot;
    //上面即为快速排序中的划分算法
    //以下就是本算法思想中所述的内容
    if(low==k)//由于与K相同,直接返回pivot元素
        return a[low];
    else if(low>k)//在前一部分表中递归寻找
        return kth_elem(a,low_temp,low-1,k);
    else//在后部分表中递归寻找
        return kth_elem(a,low,high_temp,k-low);
}

  1. 求二叉树的高度
/*
算法思想:
1、递归
2、层次遍历的时候

做题的时候问题:没有完全掌握层次遍历求高度的代码,还需要熟练一些才行
*/

//方法一:采用递归的手段来做
int Height(BiTree bt)//求二叉树bt的深度
{
    int hl,hr;//hl和hr分别是左子树和右子树的深度
    if(bt==NULL)
        return 0;
    else
    {
      hl=Height(bt->lch);
      hr=Height(bt->rch);
      if(hl>hr)
          return hl+1;
        else
          return hr+1;
    }
}
//方法二:采用层次遍历来做

int Btdepth(BiTree T)
//采用层次遍历的非递归方法求解二叉树的高度
{
    if(!T)
        return 0;
    int front=-1,rear=-1;
    int last=0,leve=0;
    BiTree Q[MaxSize];
    Q[++rear]=T;
    BiTree p;
    while(front<rear)
    {
        p=Q[++front];
        if(p->lchild)
            Q[++rear]=p->lchild;
        if(p->rchild)
            Q[++rear]=p->rchild;
        if(front==last)
        {
            level++;
            last=rear; 
        }
    }
    return level;
}
  1. 反向输出单链表
/*
算法思想:
1、头插法
2、用栈
3、递归
*/

void R_Print(Linklist L)
//从尾到头输出单链表L中每个结点的值
{
    if(L->next!=NULL)
        R_Print(L->next);//递归
    print(L->data); 
}
  1. 判断给定二叉树是否是二叉树排序树
/*
算法思想:对于二叉排序树来说,其中序遍历序列为一个递增有序序列。因此,对给定的二叉树进行中序遍历,若始终能保持前一个值比后一个值小,则说明该二叉树是一棵二叉排序树。

思路:
1、根据二叉排序树的性质,比左子树大,比右子树小
2、本题还可以用中序遍历,将元素都存储在一个数组中,再判断是否是递增的
*/

KeyType predt=-32767;           //predt为全局变量,保存当前结点中序前驱的值,初始为infit

int JudgeBST(BiTree bt)
{
    int b1,b2;
    if(bt==NULL)
        return 1;
    else
    {
        bl=JudgeBST(bt->lchild);
        if(b1==0||predt>=bt->data)
            return 0;
        predt=bt->data;
        b2=JudgeBST(bt->rchild);
        return b2;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值