NOI:1813 熄灯问题

题解链接

NOI:1813 熄灯问题_第1张图片

NOI:1813 熄灯问题_第2张图片

题解:跟poj的1753类似(https://blog.csdn.net/wuzhenzi5193/article/details/80044425),不过需要将结果保存下来

         这里的枚举只需要枚举第一行即可,然后每次后面的枚举都需要根据前一行来进行判断是否需要按灯

注意:按一个灯会改变周围的状态,但是注意此时只按了这一个灯,周围只是改变状态并没有按灯

         每次从第二列开始判断改变时,注意保存状态,每次如果此时的第一行不能满足全部熄灭的状态的话,要返回之前保存

#include 
#include 
using namespace std;
int ini[5][6];
bool tmp[5][6];
int result[5][6];
int p[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//周围
bool test(){//判断
    for(int i=0;i<5;i++){
        for(int j=0;j<6;j++){
            if(tmp[i][j])return false;
        }
    }
    return true;
}
bool iut(int x,int y){//不越界
    if(x<5&&x>=0&&y>=0&&y<6)return true;
    else return false;
}
void set(int x,int y){//改变周围状态
    if(result[x][y]==1)result[x][y]=0;//保存结果
    else result[x][y]=1;
    if(tmp[x][y])
    {
        tmp[x][y]=false;
    }
    else
    {
        tmp[x][y]=true;
    }
    for(int i=0;i<4;i++){
        if(iut(x+p[i][0],y+p[i][1])){
//            if(result[x+p[i][0]][y+p[i][1]]==1)result[x+p[i][0]][y+p[i][1]]=0;//注意按一个灯改变周围的状态,不是按一个灯周围灯也按
//            else result[x+p[i][0]][y+p[i][1]]=1;
        if(tmp[x+p[i][0]][y+p[i][1]]){
            tmp[x+p[i][0]][y+p[i][1]]=false;
        }else {
            tmp[x+p[i][0]][y+p[i][1]]=true;
        }
        }
    }
}
bool go(){//从第二行开始判断
    for(int i=1;i<5;i++){
        for(int j=0;j<6;j++){
            if(tmp[i-1][j]){
                set(i, j);
            }
        }
    }
    return test();
}
bool first(int x){//枚举所有第一行的可能性
    if(x==6){
        int tmm[5][6],tmm2[5][6];
        for(int i=0;i<5;i++){//保存当前状态
            for(int j=0;j<6;j++){
                if(tmp[i][j])tmm[i][j]=true;
                else tmm[i][j]=false;
            }
        }
        for(int i=0;i<5;i++){
            for(int j=0;j<6;j++){
                if(result[i][j]==1)tmm2[i][j]=true;
                else tmm2[i][j]=false;
            }
        }
        if(go())
        {
            return true;
        }
        else{//不符合结果,所以还原状态
            for(int i=0;i<5;i++){
                for(int j=0;j<6;j++){
                    if(tmm[i][j])tmp[i][j]=true;
                    else tmp[i][j]=false;
                }
            }
            for(int i=0;i<5;i++){
                for(int j=0;j<6;j++){
                    if(tmm2[i][j])result[i][j]=1;
                    else result[i][j]=0;
                }
            }
            return false;

        }
    }else{
        set(0, x);
        if(first(x+1))return true;
        set(0, x);
        if(first(x+1))return true;
    }
    return false;
    
}
int main(){
    for(int i=0;i<5;i++){
        for(int j=0;j<6;j++){
            cin>>ini[i][j];
            result[i][j]=0;
            if(ini[i][j]==1)tmp[i][j]=true;
            else tmp[i][j]=false;
        }
    }
    first(0);
    for(int i=0;i<5;i++){//打印结果矩阵
        for(int j=0;j<6;j++){
            cout<

你可能感兴趣的:(NOI)