zoukankan      html  css  js  c++  java
  • 枚举--百练2811--熄灯问题

    题目陈述

    这道题乍一看不会做,但听完老师的思路就变得很简单:

    虽然情况很多似乎列举不完,但是我们可以只列举第一行的所有情况,然后推出后面的所有情况,这下这道题就有了思路

    我自己写的时候没有用到下面这两句代码(也即在完整代码中高亮标记的那两句)

    press[i+1][l]=(press[i-1][l]+press[i][l-1]+press[i][l]+press[i][l+1]+light[i][l])%2;
    
    if ((press[5][c-1]+press[5][c]+press[5][c+1]+press[4][c])%2 != puzzle[5][c]);

    这两句代码非常巧妙,我感觉算是神来之笔~

    另外注意代码中的“首行所有情况枚举”算法,利用二进制数从0加到31得到了第一行的所有0|1情况,非常的巧妙,代码下文有高亮

    我自己写的时候写了一个change函数,专门来改变puzzle数组的值,但是这样子做程序得不出结果,原因暂时没有发现..

    于是在网上找到了原本代码,经过修改使其简洁得到如下代码:

    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<cctype>
    using namespace std;
    
    #define puzzle light
    
    int light[10][10]={0},press[10][10]={0};
    
    int guess(){
    	int i,l;
    	for(i=1;i<=4;i++)
    		for(l=1;l<=6;l++){
    			press[i+1][l]=(press[i-1][l]+press[i][l-1]+press[i][l]+press[i][l+1]+light[i][l])%2;
    		}
    	
        for(int c=1; c<7; c++) {
            if ((press[5][c-1]+press[5][c]+press[5][c+1]+press[4][c])%2 != puzzle[5][c]) 
    		return 0;
    	}
        
    	return 1;
    }
    
    int main(){
    //	freopen("in.txt","r",stdin);
    	int c;
    	for(int i=1;i<=5;i++)
    	for(int l=1;l<=6;l++)
    		scanf("%d",&light[i][l]);
    		
    	for(int i=1;i<=6;i++){
    		press[1][i]=0;
    	}
    	
    	while(!guess()){
    		press[1][1]++;
    		c=1;
    		while(press[1][c]>1){
    			press[1][c]=0;
    			c++;
    			press[1][c]++;
    		}
    	}
    
    	for(int i=1;i<=5;i++)
    	for(int l=1;l<=6;l++){
    		if(l!=6)
    		printf("%d ",press[i][l]);
    		else if(i!=5) printf("%d
    ",press[i][l]);
    		else printf("%d",press[i][l]);
    	}
    
    	return 0;
    }
    

      

    柳暗花明又一村
  • 相关阅读:
    Redis学习笔记
    Springboot + Tomcat跑项目出现端口被占用的问题
    按层打印二叉树
    打印二叉树的镜像——剑指offer
    判断树的子结构——剑指offer
    实习半个月的感想
    使用KMP算法判断是否为旋转词
    微信双开
    win10 右键添加cmd当前目录打开
    勒索邮件
  • 原文地址:https://www.cnblogs.com/ucandoit/p/8467644.html
Copyright © 2011-2022 走看看