暴力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;
}