第三轮测试卷一(2020.10.29)
- 铺石板,输入n x m的广场,和a x a的石板,求最少需要多少石板?
/*
算法思想:没啥。。。。
理解向上取整就行
*/
num=((n+a-1)/a)*((m+a-1)/a);
-
用的0-1背包
-
找铺水管一共有多少种铺法?
//算法思想: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;
}
- 将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;//返回最小花费
}
- 从数组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、递归
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;
}
}
}