C++ 1.颠倒黑白

温故而知新,常来复习哦!

在这里插入图片描述在这里插入图片描述
一天了呀,费了九牛二虎之力,终于有了一丝进展,相信自己,一步一步往前走!经过‘参考借鉴’,代码如下:

//翻棋子
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int l[4][4];
//int min=0x7fffffff;
int check()
{
    
    
	int i,j;
	for(i=0;i<4;++i){
    
    
		for(j=0;j<4;++j){
    
    
			if(l[i][j]!=l[0][0]){
    
    
				return -1;
		    }
		}
	}
	return 1;
}
void turn(int m,int n){
    
    
	l[m][n]=!l[m][n];
	if(m-1>=0){
    
    
		l[m-1][n]=!l[m-1][n];
	}
	if(m+1>=0){
    
    
		l[m+1][n]=!l[m+1][n];
	}
	if(n-1>=0){
    
    
		l[m][n-1]=!l[m][n-1];
	}
	if(n+1>=0){
    
    
		l[m][n+1]=!l[m][n+1];
	}
}
void dfs(int s,int M){
    
    
	int Min=0x7fffffff;
	int x,y;
	if(s==16){
    
    
		if(check()==1)
			if(M<Min){
    
    
				Min=M;
			}
		return;		
	}
	else{
    
    
		x=s/4;
		y=s%4;
		dfs(s+1,M);
		turn(x,y);
		dfs(s+1,M+1);
		turn(x,y); 
	}
}
int main()
{
    
    
	char p;
	for(int i=0;i<4;i++){
    
    
		for(int j=0;j<4;j++){
    
    
			scanf("%c",&p);
			if(p=="b") l[i][j]=0;
			else l[i][j]=1;
		}
	}
	dfs(0,0);
	if(Min==0x7fffffff){
    
    
		printf("Impossible\n");
	}
	else{
    
    
		printf("%d\n",Min);
	}
return 0;
}

但是还有错误暂时没有解决,我琢磨着先问着别人,在这里做个总结:
1.在每一个 if语句,while语句,for语句后面老老实实加上大括号,注意层次
2.一开始设置了变量 min ,但是报错:

[Error] overloaded function with no contextual type information

原因是与C++的内置函数 min 重名了,所以不要设置与C++内置函数重名的变量名
3.第一个是检查函数,以左上角状态为参照,return -1 为一个约定俗成的惯例,表示该函数失败了,类推 return 1 则函数成功了
4.第二个定义翻转函数,用 !变量 实现,用判断语句避免了边界情况
***5.***我还不是很理解,第三个定义深搜,深度优先搜索,大体的意思是从某一个未被遍历的位置出发,找到与之相邻的未被遍历的点,依次进行下去直到找不到相邻的未被遍历过的点,从而原路退一步,继续搜索相邻的未被遍历过的点(可能一个点周围有多个未被遍历过的点,而一次只能找到一个),搜索到了就往深处进行,找不到了就继续后退,直到退回原处,然后进行检查,如果所有的点都被遍历了,就完成了,反之再从某一个未被遍历过的点出发重复一开始的操作,直到所有的点都被遍历过。。再附一个比较专业的文章吧:
深度优先搜索
此题的遍历方式是从左往右,从上往下,巧妙运用了整除号与取余符号遍历每一行的每一列,但是我不很明白其中迭代的含义,哪位大佬能解答一下吗?小弟真的感激不尽!
6.最后让我们看一看我们的报错:
在这里插入图片描述
if(p==“b”) l[i][j]=0; 报错,但我不理解为什么
if(Min==0x7fffffff) 同样不清楚为什么错,我很奇怪,怎么让这个 Min 在其它的函数中被调用呢?
写到这里,说真的,我想先把这道题放一放吧,就我的水平来看要想将它完全搞懂真的比较困难,怪我自己学术不精了,但是,做人要乐观,即使是错误的,也要大胆的展示出来,因为,这只是我未来成功路上的垫脚石而已,我有朝一日会蔑视这道题的!
看一个大佬的代码:


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
 
using namespace std;
int a[4][4];
 
int Min=0x7fffffff;
int check()//检查棋子是否同色
{
    
    
    int i,j;
    for(i=0; i<4; ++i)
        for(j=0; j<4; ++j)
            if(a[i][j]!=a[0][0])
                return -1;
    return 1;
}
 
void change(int i,int j){
    
    
    a[i][j]=!a[i][j];
    if(i-1>=0){
    
    
        a[i-1][j]=!a[i-1][j];
    }
    if(j-1>=0){
    
    
        a[i][j-1]=!a[i][j-1];
    }
    if(i+1<4){
    
    
        a[i+1][j]=!a[i+1][j];
    }
    if(j+1<4){
    
    
        a[i][j+1]=!a[i][j+1];
    }
}
 
 
void dfs(int d,int k)
{
    
    
    int x,y;
    if(d==16){
    
    
        if(check()==1)
            if(k<Min)
                Min=k;
        return;
    }else{
    
    
        x=d/4;//行
        y=d%4;//列
        dfs(d+1,k);
        change(x,y); //翻过去
        dfs(d+1,k+1);
        change(x,y);  //别忘了翻回去,这个是返回原来的状态
    }
}
 
 
int main()
{
    
    
    char t;
    for(int i=0;i<4;i++){
    
    
        for(int j=0;j<4;j++){
    
    
            cin>>t;
            if(t=='b') a[i][j]=0;
            else a[i][j]=1;
        }
    }
    dfs(0,0);
    if(Min==0x7fffffff)
        cout<<"Impossible"<<endl;
    else
        cout<<Min<<endl;
 
return 0;
}

//转自flip game

我不清楚为什么我的就不行了呢,差不了多少啊!
又思考了一下:改为如下:

//翻棋子
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int l[4][4];
int Min=0x7fffffff;
//最大的十六进制数
//还是要定义在外面!解决第一个错误
int check()
{
    
    
	int i,j;
	for(i=0;i<4;++i){
    
    
		for(j=0;j<4;++j){
    
    
			if(l[i][j]!=l[0][0]){
    
    
				return -1;
		    }
		}
	}
	return 1;
}
void turn(int m,int n){
    
    
	l[m][n]=!l[m][n];
	if(m-1>=0){
    
    
		l[m-1][n]=!l[m-1][n];
	}
	if(m+1>=0){
    
    
		l[m+1][n]=!l[m+1][n];
	}
	if(n-1>=0){
    
    
		l[m][n-1]=!l[m][n-1];
	}
	if(n+1>=0){
    
    
		l[m][n+1]=!l[m][n+1];
	}
}
void dfs(int s,int M){
    
    
	int x,y;
	if(s==16){
    
    
		if(check()==1){
    
    
			if(M<Min){
    
    
				Min=M;
			}
		}
		return;		
	}
	else{
    
    
		x=s/4;
		y=s%4;
		dfs(s+1,M);
		turn(x,y);
		dfs(s+1,M+1);
		turn(x,y); 
	}
}
int main()
{
    
    
	char p;
	for(int i=0;i<4;i++){
    
    
		for(int j=0;j<4;j++){
    
    
			scanf("%c",&p);
			if(p=='b') l[i][j]=0;
			else l[i][j]=1;
		}
	}
	dfs(0,0);
	if(Min==0x7fffffff){
    
    
		printf("Impossible\n");
	}
	else{
    
    
		printf("%d\n",Min);
	}
return 0;
}

先搞懂两件事:
1.i++ 与 ++i 的区别
比较好理解,就不赘述了:
C语言 i++ 与 ++i 的区别
2.单引号与双引号
一句话,但我不知道:
单引号:字符,上面报错的原因也在于此,我用成了双引号
双引号:字符串类型
但是!
在这里插入图片描述

输入测试样例结果为8!而正确结果是4啊,我的自信回来了,别急!让我们慢慢来看
找到了:将

if(m-1>=0){
    
    
		l[m-1][n]=!l[m-1][n];
	}
	if(m+1>=0){
    
    
		l[m+1][n]=!l[m+1][n];
	}
	if(n-1>=0){
    
    
		l[m][n-1]=!l[m][n-1];
	}
	if(n+1>=0){
    
    
		l[m][n+1]=!l[m][n+1];
	}

改为

if(m-1>=0){
    
    
		l[m-1][n]=!l[m-1][n];
	}
	if(m+1<4){
    
    
		l[m+1][n]=!l[m+1][n];
	}
	if(n-1>=0){
    
    
		l[m][n-1]=!l[m][n-1];
	}
	if(n+1<4){
    
    
		l[m][n+1]=!l[m][n+1];
	}

理解错误,左右都不能超范围啊!
但是!
输出:

Impossible

还是有问题呀!继续DEBUG!
现在我们的代码是这样:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int l[4][4];
int Min=0x7fffffff;
//还是要定义在外面!解决第一个错误
int check()
{
    
    
	int i,j;
	for(i=0;i<4;++i){
    
    
		for(j=0;j<4;++j){
    
    
			if(l[i][j]!=l[0][0]){
    
    
				return -1;
		    }
		}
	}
	return 1;
}
void turn(int m,int n){
    
    
	l[m][n]=!l[m][n];
	if(m-1>=0){
    
    
		l[m-1][n]=!l[m-1][n];
	}
	if(m+1<4){
    
    
		l[m+1][n]=!l[m+1][n];
	}
	if(n-1>=0){
    
    
		l[m][n-1]=!l[m][n-1];
	}
	if(n+1<4){
    
    
		l[m][n+1]=!l[m][n+1];
	}
}
void dfs(int s,int M){
    
    
	int x,y;
	if(s==16){
    
    
		if(check()==1){
    
    
			if(M<Min){
    
    
				Min=M;
			}
		}
		return;		
	}
	else{
    
    
		x=s/4;
		y=s%4;
		dfs(s+1,M);
		turn(x,y);
		dfs(s+1,M+1);
		turn(x,y); 
	}
}
int main()
{
    
    
	char p;
	for(int i=0;i<4;i++){
    
    
		for(int j=0;j<4;j++){
    
    
			scanf("%c",&p);
			if(p=='b') l[i][j]=0;
			else l[i][j]=1;
		}
	}
	dfs(0,0);
	if(Min==0x7fffffff){
    
    
		printf("Impossible\n");
	}
	else{
    
    
		printf("%d\n",Min);
	}
return 0;
}

大写的
WHY??
容我休息一下继续想!!
越努力越幸运!
虽然我现在一无所知!
但我相信经过自己的努力我可以越来越好!!
等待自己 D E B U G !!!
等我元气归来,哼!
/
我渐渐意识到,这不是哪里出了错误!还是代码有问题吧!我对代码与答案代码进行了比较,重点对不同之处进行分析,
我们输出 l 看一看:

0x4ac040

竟然不是 0 1 数组!我又晕了,哪里的问题呢啊啊啊~
原来这是16进制,吓我这条菜狗一跳!通过对比,l 输出已经出现了问题,正确答案输出 l :

0x4a7040

哎~我就改了下输入输出的格式,怎么就解决了呢?!不理解!

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int l[4][4];
int Min=0x7fffffff;
//还是要定义在外面!解决第一个错误
int check()
{
    
    
	int i,j;
	for(i=0;i<4;++i){
    
    
		for(j=0;j<4;++j){
    
    
			if(l[i][j]!=l[0][0]){
    
    
				return -1;
		    }
		}
	}
	return 1;
}
void turn(int m,int n){
    
    
	l[m][n]=!l[m][n];
	if(m-1>=0){
    
    
		l[m-1][n]=!l[m-1][n];
	}
	if(m+1<4){
    
    
		l[m+1][n]=!l[m+1][n];
	}
	if(n-1>=0){
    
    
		l[m][n-1]=!l[m][n-1];
	}
	if(n+1<4){
    
    
		l[m][n+1]=!l[m][n+1];
	}
}
void dfs(int s,int M){
    
    
	int x,y;
	if(s==16){
    
    
		if(check()==1){
    
    
			if(M<Min){
    
    
				Min=M;
			}
		}
		return;		
	}
	else{
    
    
		x=s/4;
		y=s%4;
		dfs(s+1,M);
		turn(x,y);
		dfs(s+1,M+1);
		turn(x,y); 
	}
}
int main()
{
    
    
	char p;
	for(int i=0;i<4;i++){
    
    
		for(int j=0;j<4;j++){
    
    
			cin>>p;
			if(p=='b') l[i][j]=0;
			else l[i][j]=1;
		}
	}
	dfs(0,0);
	if(Min==0x7fffffff){
    
    
		cout<<"Impossible"<<endl;
	}
	else{
    
    
		cout<<Min<<endl;
	}
return 0;
}

(定睛一看成了改了字母的答案~哎·!!)
但是是为什么呢?
两种输入输出方式值得我去研究一下!!!
越努力越幸运!
和ZDZ一起加油鸭!

猜你喜欢

转载自blog.csdn.net/interestingddd/article/details/113524316
今日推荐