题目来源:蓝桥杯真题题号118,名字为机器人塔。
链接:
最后过关的代码:
#include <stdio.h>
#include <stdlib.h>
char arr[500][500]={'\0'};
int ans = 0;
int m,n;
int Check(int f){
for (int j = 0; j <= f; j++){
if(arr[f - 1][j] == 'a'){
if(arr[f][j] != arr[f][j + 1]){
return 0;
}
}
if(arr[f - 1][j] == 'b'){
if(arr[f][j] == arr[f][j + 1]){
return 0;
}
}
}
return 1;
}
void DFS(int M,int N, int count,int f){
if(M == 0 && N == 0){
if(Check(f)){
ans++;
return;
}
}
if(f > 0 && count == (f + 1)){
if(!Check(f)){
return;
}
}
if(count == (f + 1) ){
DFS(M,N,0,f+1);
}
else{
if(M > 0){
arr[f][count] = 'a';
DFS(M-1,N,count+1,f);
}
if(N > 0){
arr[f][count] = 'b';
DFS(M,N-1,count+1,f);
}
}
}
int main(int argc, char *argv[])
{
scanf("%d %d",&m,&n);
DFS(m,n,0,0);
printf("%d",ans);
return 0;
}
过关前的一次测试:
#include <stdio.h>
#include <stdlib.h>
char arr[30][30]={'\0'};
int ans = 0;
int m,n;
int Check(int f){
for (int i = 0; i < f; i++){
for (int j = 0; j <= i; j++){
if(arr[i][j] == 'a'){
if(arr[i + 1][j] != arr[i + 1][j + 1]){
return 0;
}
}
if(arr[i][j] == 'b'){
if(arr[i + 1][j] == arr[i + 1][j + 1]){
return 0;
}
}
}
}
return 1;
}
void DFS(int M,int N, int count,int f){
if(M == 0 && N == 0){
if(Check(f)){
ans++;
}
return;
}
if(count == (f + 1) ){
DFS(M,N,0,f+1);
}
else{
if(M > 0){
arr[f][count] = 'a';
DFS(M-1,N,count+1,f);
}
if(N > 0){
arr[f][count] = 'b';
DFS(M,N-1,count+1,f);
}
}
}
int main(int argc, char *argv[])
{
scanf("%d %d",&m,&n);
DFS(m,n,0,0);
printf("%d",ans);
return 0;
}
优化部分
优化的部分是在深搜过程中check函数由最后M与N次数用完后从第一行到最后一行的检查,到每一行输入后以当前行和上一行进行错误检查。第一段代码可以在输入的过程中淘汰掉排列非法的组合,相对第二段减少了运行时间。
原①
int Check(int f){
for (int i = 0; i < f; i++){
for (int j = 0; j <= i; j++){
if(arr[i][j] == 'a'){
if(arr[i + 1][j] != arr[i + 1][j + 1]){
return 0;
}
}
if(arr[i][j] == 'b'){
if(arr[i + 1][j] == arr[i + 1][j + 1]){
return 0;
}
}
}
}
return 1;
}
优化后①
int Check(int f){
for (int j = 0; j <= f; j++){
if(arr[f - 1][j] == 'a'){
if(arr[f][j] != arr[f][j + 1]){
return 0;
}
}
if(arr[f - 1][j] == 'b'){
if(arr[f][j] == arr[f][j + 1]){
return 0;
}
}
}
return 1;
}
原②
if(M == 0 && N == 0){
if(Check(f)){
ans++;
}
return;
}
优化后②
if(M == 0 && N == 0){
if(Check(f)){
ans++;
return;
}
}
if(f > 0 && count == (f + 1)){
if(!Check(f)){
return;
}
}
明显的变化在于从双层从头开始的循环到每次每行输入完之后的检测,时间复杂度明显减小。
PS
新手写的,代码或排版写的不好,大佬可以提提意见^_^)>