[DFS][洛谷] P2040 打开所有的灯

暴力dfs

将状态转换为数字串, 用map记录当前状态的最小步数

若大于当前步则可剪枝

搜完后输出MAP中全1的步数即可

解法二

可以证明一个点重复点击是无效的

因此每次搜完打标记延展出的路不搜重复点再回溯更快也更容易

做题时没有推出了这个结论 写了发暴力DFS将所有状况搜完了

//#pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
typedef long long ll;
const ll MAXN = 1e6 + 10;

bool arr[5][5];

ll ans = 0x3f3f3f3f;

map <ll, ll> MP;

void oprt(ll x, ll y)
{
    arr[x][y] ^= 1;
    arr[x - 1][y] ^= 1;
    arr[x + 1][y] ^= 1;
    arr[x][y - 1] ^= 1;
    arr[x][y + 1] ^= 1;
}

bool judge()
{
    ll ret;
    for(ll i = 1; i <= 3; i++)
        for(ll j = 1; j <= 3; j++)
            ret += arr[i][j];
    if(ret == 9)
    	return true;
    else
    	return false;
}

ll rec()
{
    ll ret = 1;
    for(ll i = 1; i <= 3; i++)
        for(ll j = 1; j <= 3; j++)
            ret = (ret * 10 + arr[i][j]);
    return ret;
}

void dfs(ll x, ll y, ll step)
{
	ll ret = rec();
//	if(step > 10)
//		return ;
		
    if(MP[ret] != 0 && MP[ret] <= step)
    {
        return ;
    }

    else
    {
        MP[ret] = step;

        if(judge())
        {
        	ans = min(ans, step);
        	return ;
		}    

        for(ll i = 1; i <= 3; i++)
        {
            for(ll j = 1; j <= 3; j++)
            {
				if(i != x || j != y)
				{
					oprt(i, j);
	                dfs(i, j, step + 1);
	                oprt(i, j);
				}   
            }
        }
    }
}

signed main()
{
    //ios::sync_with_stdio(false);
    //cin.tie(0);     cout.tie(0);
    //freopen("D://test.in", "r", stdin);
    //freopen("D://test.out", "w", stdout);
    
    for(ll i = 1; i <= 3; i++)
        for(ll j = 1; j <= 3; j++)
            cin>>arr[i][j];

    for(ll i = 1; i <= 3; i++)
    {
        for(ll j = 1; j <= 3; j++)
        {
            oprt(i, j);
            dfs(i, j, 1);
            oprt(i, j);
        }
    }

    cout<<MP[1111111111]<<endl;
        
    return 0;
}

 

posted @ 2018-10-18 09:53  张浦  阅读(107)  评论(0编辑  收藏  举报