第三轮测试卷一(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小数值
/*
算法思想:在进行快速排序的过程中,每轮遍历,之后,对于枢轴元素进行判断
这种思想很新,自己要学会掌握。主要对于题目如果有要求,时间复杂度要尽可能低的时候。
*/