• 洛谷 P2040 打开所有的灯 题解


    这个题写其他题解的dalao们已经解释了

    一个灯最多开一次(如果实在不知道为什么看评论区)

    这个题一共就9个灯嘛,对吧

    递归好想不好写(对于我这种蒟蒻)

    所以我写了一个所有题解中最暴力的

    直接枚举9个灯的开关状态就可以了

    我们把原先的数组开半天在初始化不如弄一个已经全开了的数组开半天看看能不能返回原先的状态就好了更方便一点

    //打开所有的灯 九层循环法
    #include<bits/stdc++.h>
    
    using namespace std;
    
    inline int read() {//快读
    	int s=0,w=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9') {
    		if(ch=='-')w=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    	return s*w;
    }
    inline void write(int x) //快写{
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10+'0');
    }
    
    int b[11][11],c[11][11],a[11][11],tot,zx = 999;
    int xx[] = {0,1,-1,0,0},yy[] = {0,0,0,1,-1},d[10];
    
    int pd(int x) {//判断在哪一行
    	if(x <= 3)
    		return 1;
    	if(x >= 7)
    		return 3;
    	return 2;
    }
    
    void kd(int x,int y) {//开它周围的灯
    	for(int i = 0; i <= 4; ++i) {
    		int x2 = x + xx[i] , y2 = y + yy[i];
    		c[x2][y2] == 1 ? c[x2][y2] = 0 : c[x2][y2] = 1;
    	}
    }
    
    bool jc() {//判断是否全打开了
    	for(int i = 1; i <= 3; ++i)
    		for(int j = 1; j <= 3; ++j)
    			if(a[i][j] != c[i][j])
    				return 0;
    	return 1;
    }
    
    int main(int argc, char const *argv[]) {
    	for(int i = 1; i <= 3; ++i)//读入并初始化c
    		for(int j = 1; j <= 3; ++j) {
    			a[i][j] = read();
    			c[i][j] = 1;
    		}
    	int he = 0;
    	for(d[1] = 0; d[1] <= 1; ++d[1])
    		for(d[2] = 0; d[2] <= 1; ++d[2])
    			for(d[3] = 0; d[3] <= 1; ++d[3])
    				for(d[4] = 0; d[4] <= 1; ++d[4])
    					for(d[5] = 0; d[5] <= 1; ++d[5])
    						for(d[6] = 0; d[6] <= 1; ++d[6])
    							for(d[6] = 0; d[6] <= 1; ++d[6])
    								for(d[7] = 0; d[7] <= 1; ++d[7])
    									for(d[8] = 0; d[8] <= 1; ++d[8])
    										for(d[9] = 0; d[9] <= 1; ++d[9]) {
    											for(int i = 1; i <= 9; ++i) {
    												if(d[i] == 1) {//如果开着
    													kd(pd(i),i % 3 == 0 ? 3 : i % 3);开灯
    													he ++;//计数器
    													if(he > zx)//如果不是正解直接退出
    														break;
    												}
    											}
    											if(jc() && he < zx) {//如果全都开了并且比最小值小
    												zx = he;
    											}
    											he = 0;
    											for(int i = 1; i <= 3; ++i)//清空数组
    												for(int j = 1; j <= 3; ++j)
    													c[i][j] = 1;
    										}
    	write(zx);
    	cout<<endl;
    	return 0;
    }
    

    友情赠送(递归版本)

    //打开所有的灯 递归法
    #include<bits/stdc++.h>
    
    using namespace std;
    
    inline int read() {
    	int s=0,w=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9') {
    		if(ch=='-')w=-1;
    		ch=getchar();
    	}
    	while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    	return s*w;
    }
    inline void write(int x) {
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10+'0');
    }
    
    int b[11][11],c[11][11],a[11][11],tot,zx = 999;
    int xx[] = {0,1,-1,0,0},yy[] = {0,0,0,1,-1},d[10];
    
    void kd(int x,int y) {
    	for(int i = 0; i <= 4; ++i) {
    		int x2 = x + xx[i] , y2 = y + yy[i];
    		c[x2][y2] == 1 ? c[x2][y2] = 0 : c[x2][y2] = 1;
    	}
    }
    
    bool jc() {
    	for(int i = 1; i <= 3; ++i)
    		for(int j = 1; j <= 3; ++j)
    			if(a[i][j] != c[i][j])
    				return 0;
    	return 1;
    }
    
    void dg(int x,int y,int tot) {
    	if(x == 4) {
    		if(jc() == 1)
    			zx = min(zx,tot);
    		return ;
    	}
    	kd(x,y);
    	y == 3 ? dg(x + 1,1,tot + 1) : dg(x,y + 1,tot + 1);
    	kd(x,y);
    	y == 3 ? dg(x + 1,1,tot) : dg(x,y + 1,tot);
    }
    
    int main(int argc, char const *argv[]) {
    	for(int i = 1; i <= 3; ++i)
    		for(int j = 1; j <= 3; ++j) {
    			a[i][j] = read();
    			c[i][j] = 1;
    		}
    	int he = 0;
        dg(1,1,0);
        write(zx);
    	cout<<endl;
    	return 0;
    }
    
  • 相关阅读:
    C语言 · 阶乘计算 · 基础练习
    C语言 · 查找整数 · 基础练习
    UML课程复习重点
    运维参考
    mysql语法总结
    Python杂篇
    Python练习题
    Python参考
    k8s中ipvs和iptables选择
    安装cni网络插件-非必须
  • 原文地址:https://www.cnblogs.com/lztzs/p/11100868.html
Copyright © 2020-2023  润新知