GDUT_寒假训练题解报告_专题I_B、C、D题 个人题解报告

GDUT_寒假训练题解报告_专题I_B、C、D题 个人题解报告


B题 :dfs (我更喜欢叫它感染函数,因为之前写扫雷的时候教别人,不敢说dfs就说感染函数说顺口了。)

由于最近下雨,水在农民约翰的田里的各个地方汇集起来,用一个N×M(1<=N<=100;1<=M<=100)正方形表示。每一个正方形包含水(“W”)或旱地(“.”)。农场主约翰想弄清楚他的田里有多少池塘。池塘是一组有水的相连的正方形,其中一个正方形被认为与它的八个邻居相邻。

给一张农夫约翰的田地图,确定他有多少池塘。

输入

*第1行:两个空格分隔的整数:N和M

*每行2…N+1:M个字符,代表一行农民约翰的田地。每个字符都是“W”或“.”。字符之间没有空格。

输出

*第1行:农民约翰田地里的池塘数量。

样例输入
10 12
W . . . . . . . . WW .
. WWW . . . . . WWW
. . . . WW . . . WW .
. . . . . . . . . WW .
. . . . . . . . . W . .
. . W . . . . . . W . .
. W . W . . . . . WW .
W . W . W . . . . . W .
. W . W . . . . . . W .
. . W . . . . . . . W .

样例输出:
3

这个就没什么好说的了,普普通通的过河拆桥式dfs,找到一个w然后能联通的都给他感染了,同时自己还变成了’ . '以绝后路。

上代码:

using namespace std;
int n, m;
void dfs(int,int);
char all[110][110];
int main()
{
	scanf ( "%d %d", &n, &m );
	for ( int time = 0; time < n; time++ )
	{
		for ( int time1 = 0; time1 < m; time1++ )
		{
			scanf ( " %c", &all[time][time1] );
		}
	}
	int sum=0;
	for(int time=0;time<n;time++)
	{
		for(int time1=0;time1<m;time1++)
		{
			if(all[time][time1]=='W'){dfs(time,time1);sum++;}
		}
	}
//	for ( int time = 0; time < n; time++
//	{
//		for ( int time1 = 0; time1 < m; time1++ )
//		{
//			printf ( "%c", all[time][time1] );
//		}
//		printf("\n");
//	}
	printf("%d\n",sum);

	return 0;
}
inline bool ilegal(int a,int b){
	return a<0||b<0||a>=n||b>=m;
}
void dfs(int a,int b)
{
	all[a][b]='.';

	for(int time=-1;time<2;time++)
	{
		for(int time1=-1;time1<2;time1++)
		{
			//if((time!=0)&&(time1!=0))
			{
				if(!ilegal(a+time,b+time1)&&(all[a+time][b+time1]=='W'))
				dfs(a+time,b+time1);
			}
		}
	}
	return ;
}

积累小用法:ilegal函数判定一个东西是否合法,简化步骤,十分常用




C题: dfs

有一个长方形的房间,上面铺着方砖。每个瓷砖都是红色或黑色的。一个男人站在一块黑色的瓷砖上。从一个瓷砖,他可以移动到四个相邻瓷砖之一。但他不能在红瓦上移动,只能在黑瓦上移动。

编写一个程序,通过重复上述动作来计算他可以达到的黑色瓷砖的数量。

输入

输入由多个数据集组成。数据集以包含两个正整数W和H的行开头;W和H分别是x和y方向上的平铺数。W和H不超过20。

数据集中还有H行,每行包含W个字符。每个字符代表一个瓷砖的颜色,如下所示。
‘.’-一块黑色的瓷砖
“35;”-红色瓷砖
“@”-一个站在黑色瓷砖上的人(在数据集中只出现一次)
输入端由一条由两个零组成的线表示。

输出

对于每个数据集,您的程序应该输出一行,其中包含他可以从初始平铺(包括其本身)到达的平铺数。

样本输入

6 9
. . . . # .
. . . . . #
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
#@…#
.#…#.
11 9
.#…
.#.#######.
.#.#…#.
.#.#.###.#.
.#.#…@#.#.
.#.#####.#.
.#…#.
.#########.

11 6
…#…#…#…
…#…#…#…
…#…#…###
…#…#…#@.
…#…#…#…
…#…#…#…
7 7
…#.#…
…#.#…
###.###
…@…
###.###
…#.#…
…#.#…
0 0

样例输出:

45
59
6
13

此题与B题大同小异,不再赘述,直接代码:

using namespace std;
int line,arr;
char all[21][21];
void dfs(int x,int y);
int sum=0;
int check(int a,int b);

int main()
{
	while(~scanf("%d %d",&line,&arr))
	{
		if(line==0||arr==0)return 0;
		int start_x,start_y;
		sum=0;
		getchar();
		for(int time=0;time<arr;time++)
		{
			for(int time1=0;time1<line;time1++)
			{
				all[time][time1]=getchar();
				if(all[time][time1]=='@'){start_x=time;start_y=time1;}
			}
			getchar();
		}
		//input finished
		dfs(start_x,start_y);
		printf("%d\n",sum);
	}

	return 0;
}

void dfs(int x,int y)
{
	all[x][y]='#';
	sum++;
	if(check(x-1,y)&&all[x-1][y]=='.')dfs(x-1,y);
	if(check(x+1,y)&&all[x+1][y]=='.')dfs(x+1,y);
	if(check(x,y-1)&&all[x][y-1]=='.')dfs(x,y-1);
	if(check(x,y+1)&&all[x][y+1]=='.')dfs(x,y+1);

}
int check(int a,int b)
{
	if(a<arr&&a>-1&&b<line&&b>-1)return 1;
	else return 0;
}



D题: dfs(模板题)

这个比BC题多了花样,

我有N颗宝石,打算用其中的K颗做项链给我妈妈,但她不会接受太重的项链。考虑到每一颗宝石的价值和重量,请帮我找出我妈妈会接受的最值钱的项链。

输入

输入的第一行是案例数。
对于每种情况,第一行包含两个整数N(N<=20),即石头的总数,K(K<=N),即制作项链的石头的确切数目。

接下来是N行,每行包含两个整数:a(a<=1000),表示每一块宝石的价值;b(b<=1000),表示宝石的重量。

每一行的最后一行包含一个整数w,我母亲接受的最大权重,w=1000。

输出

对于每种情况,输出项链的最大可能值。

样例输入
1
2 1
1 1
1 1
3
样本输出
1

这个题目比BC题目多了花样,首先是N个物品,取C个,使得这C个物品重量不超过妈妈的脖子的最大接受重量,还能最贵,就是一看数据就是爆搜的背包问题

代码如下:

using namespace std;

int N;
int K;
int V[21];
int W[21];
void dfs(int value,int weight,int i,int num);
int accepted_weight;
int _Max;
int main()
{
	int t;
	scanf("%d",&t);
	for(int time=0;time<t;time++)
	{
		_Max=INT_MIN;

		scanf("%d %d",&N,&K);

		for(int time1=0;time1<N;time1++)
		{
			scanf("%d %d",&V[time1],&W[time1]);
		}
		scanf("%d",&accepted_weight);
		dfs(0,0,0,0);

		printf("%d\n",_Max);
	}
	return 0;
}

void dfs(int value,int weight,int i,int num)
{
	if(i==N){if(_Max<value)_Max=value;}
	else
	{
		if(weight+W[i]<accepted_weight&&num<K)dfs(value+V[i],weight+W[i],i+1,num+1);
		dfs(value,weight,i+1,num);
	}

	return ;
}

处理好dfs的参数意义,也是比较容易就能A的

发布了8 篇原创文章 · 获赞 0 · 访问量 117

猜你喜欢

转载自blog.csdn.net/DevourPower/article/details/103952282