CSP-《I‘m stuck!》-感悟

题目

在这里插入图片描述
在这里插入图片描述

做题过程

注:黄色高亮表示需要注意的地方,蓝色粗体表示代码思路

好久没有写过代码了,今天做这道编程题,简直是灾难现场。

上午编程完后发现样例没有通过,检查发现算法思路出现了问题:我计数了S不能到达的格子。【要重视题目中的所有条件,特别时限制条件】
中午吃完饭后重新整理了思路:使用DFS分别标记可以从S出发到达的格子和可以到达T的格子,两种标记分别放在F1和F2数组中,其中1表示标记。

接下来又遇到了编译错误的问题,借鉴网上的说法直接再代码前加入一下万能引入便通过了:
#include <bits/stdc++.h>
using namespace std;

编译通过后,系统显示我只有10分,我检查了代码的思路,使用各种样例检查也没有问题。我自己写了个生成随机样例的代码:

#include<bits/stdc++.h>
using namespace std;

#define R 50
#define C 50

int main(){
	//随机生成地图 
	char M[8]={'+','.','+','|','+','-','+','#'};
	char a[R][C];
	srand((unsigned int)time(NULL));
	for(int i = 0; i < R; i++)
		for(int j = 0; j < C; j++)
			a[i][j]=M[rand() % 8];
	srand((unsigned int)time(NULL));
	a[rand() % R][rand() % C] = 'S';
	a[rand() % R][rand() % C] = 'T';
	
	//输出到文件 
	FILE* fp = fopen("C:/Users/kaoyan/Desktop/test.txt", "w");
	fprintf(fp,"%d %d\n",R, C);	
	for(int i = 0; i < R; i++){
		for(int j = 0; j < C; j++)
			fprintf(fp,"%c",a[i][j]);
		fprintf(fp,"\n");
	}
	fclose(fp);
	return 0;
}

我在dev-c++尝试了很多次都没有问题,这使我很烦恼。纠结了一下午。
吃完晚饭后,我仔细想了想,那么多样例都没有问题,我的代码应该时没有问题的,而代码在dev-c++上运行和提交到系统运行的区别就在于输入不同,我便去检查了输入那部分的代码。我尝试去注释掉fflush(stdin);后再提交惊奇地发现时满分o( ̄▽ ̄)ブ在这里插入图片描述
我想,这可能是因为系统后台是不标准输入,至于避免回车换行地读入,只需要在后面的scanf中加上空格就行:scanf(" %c",MAP + i);

代码

#include <bits/stdc++.h>
using namespace std;

int R, C, S, T; //S记录开始位置, T记录目标位置 
char *MAP; //地图
char *F1; //非0格子表示可以从起点S到达的格子 
char *F2; //非0格子表示可以到达目T的格子 

//从格子G是否可以上移
bool CanUp(int G){
	if(G-C>=0 && MAP[G-C]!='#' && (MAP[G]=='+'||MAP[G]=='S'||MAP[G]=='T'||MAP[G]=='|'))
		return true;
	else
		return false;
}

//从格子G是否可以下移
bool CanDown(int G){
	if(G+C<R*C && MAP[G+C]!='#' && (MAP[G]=='+'||MAP[G]=='S'||MAP[G]=='T'||MAP[G]=='|'||MAP[G]=='.'))
		return true;
	else
		return false;
}

//从格子G是否可以左移
bool CanLeft(int G){
	if(G%C>0 && MAP[G-1]!='#' && (MAP[G]=='+'||MAP[G]=='S'||MAP[G]=='T'||MAP[G]=='-'))
		return true;
	else
		return false;
}

//从格子G是否可以右移
bool CanRight(int G){
	if(G%C<C-1 && MAP[G+1]!='#' && (MAP[G]=='+'||MAP[G]=='S'||MAP[G]=='T'||MAP[G]=='-'))
		return true;
	else
		return false;
}

//递归遍历可以从G到达的邻居并更改F1 
void ToNeighbor(int G){
	int n;//邻居位置
	//向上走 
	n = G - C; 
	if(!F1[n] && CanUp(G)){
		F1[n] = 1;
		ToNeighbor(n);
	}
	//向下走 
	n = G + C; 
	if(!F1[n] && CanDown(G)){
		F1[n] = 1;
		ToNeighbor(n);
	}
	//向左走 
	n = G - 1; 
	if(!F1[n] && CanLeft(G)){
		F1[n] = 1;
		ToNeighbor(n);
	}
	//向右走 
	n = G + 1; 
	if(!F1[n] && CanRight(G)){
		F1[n] = 1;
		ToNeighbor(n);
	}
}

//递归遍历可以到达G的邻居并更改F2
void FromNeighbor(int G){
	int n;//邻居位置
	//判断上邻居
	n = G - C;
	if(n >= 0 && MAP[n] != '#' && !F2[n] && CanDown(n)){
		F2[n] = 1;
		FromNeighbor(n);
	}
	//判断下邻居
	n = G + C;
	if(n < R*C && MAP[n] != '#' && !F2[n] && CanUp(n)){
		F2[n] = 1;
		FromNeighbor(n);
	}
	//判断左邻居
	n = G - 1;
	if(G%C > 0 && MAP[n] != '#' && !F2[n] && CanRight(n)){
		F2[n] = 1;
		FromNeighbor(n);
	}
	//判断右邻居
	n = G + 1;
	if(G%C < C-1 && MAP[n] != '#' && !F2[n] && CanLeft(n)){
		F2[n] = 1;
		FromNeighbor(n);
	}
}

int main(){
	
	//初始化 
	scanf("%d%d",&R,&C); 
	//fflush(stdin);
	MAP = (char*)malloc(sizeof(char) * R * C);
	F1 = (char*)malloc(sizeof(char) * R * C);
	F2 = (char*)malloc(sizeof(char) * R * C);
	for(int i = 0; i < R * C; i++){
		scanf(" %c",MAP + i);
		if(MAP[i] == 'S')
			S = i;
		if(MAP[i] == 'T')
			T = i;
		F1[i] = 0;
		F2[i] = 0;  
	}
	
	//填充F1(非0格子表示可以从起点到达的格子 ) 
	F1[S] = 1;
	ToNeighbor(S);//递归遍历可以从S到达的格子并更改F1 
	
	//填充F2(非0格子表示可以到达目的的格子) 
	F2[T] = 1;
	FromNeighbor(T);//递归遍历可以到达的T的格子并更改F1 
	
	if(!F1[T]){//从S不能到达T 
		printf("I'm stuck!");
		return 0;
	}
	
	//计数有特征的格子个数
	int q = 0;
	for(int i = 0; i < R*C; i++)
		if(F1[i] == 1 && F2[i] == 0)
			q++;
		
	printf("%d",q);
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诸葛思颖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值