#include<iostream>
#include<cstring>
#define SIZE 10
/*
* AUTHOR : benbendog
* DATE : 2010/12/18
* PROBLEM: given a map of #,O (light off ,on) ,find the minimum switches
* to turn off all the O, once a switch at (i,j) is used,
* the values of 4 neighbors of (i,j) and (i,j) would flipped
* for example, ### #O#
* #O# flip (2,2) O#O
* ### #O#
* SOLUTION: The problem is which switch we have to turn off.
when inspected row by row, row (i,j) would need to
* switch when row(i-1,j) is on, this is because
* we assume the inspected row is all off
* then the problem is the first row has nothing to
* depend on. Thus, we can generate all the possibilites
* of on/off for the first row (2^10)
*/
using namespace std;
bool choose[SIZE];
bool t[SIZE][SIZE];
bool m[SIZE][SIZE];
int dx[]={1,-1,0,0,0};
int dy[]={0,0,1,-1,0};
int ans;
void switching(int x,int y);
void recur(int p);
bool complete();
int main()
{
char ch[1000];
while(cin>>ch && strcmp(ch,"end"))
{
int i,j;
char c;
for(i = 0 ;i < SIZE ; i++)
for(j = 0 ;j < SIZE ;j++)
{
cin>>c;
if(c=='#')m[i][j] = false;
else m[i][j] = true;
}
ans = 101;
recur(0);
cout<<ch<<' ';
if(ans==101)cout<<-1<<endl;
else cout<<ans<<endl;
}
return 0;
}
void recur(int p)
{
if(p==SIZE)
{
int temp = 0;
memcpy(t,m,sizeof(m));
for(int i = 0 ;i < SIZE ; i++)
{
if(choose[i]){switching(0,i);temp++;}
}
for(int i = 1 ;i < SIZE ; i++)
for(int j = 0 ;j < SIZE ; j++)
if(t[i-1][j])
{
switching(i,j);temp++;
}
if(complete()){ans = min(ans,temp);}
}
else
{
choose[p] = true;
recur(p+1);
choose[p]= false;
recur(p+1);
}
}
bool complete()
{
int i,j;
for(i = 0 ;i < SIZE ; i++)
for(j = 0 ;j < SIZE ;j++)
if(t[i][j])return false;
return true;
}
void switching(int x,int y)
{
int tx,ty;
for(int i = 0 ;i < 5 ; i++)
{
tx = x + dx[i];
ty = y + dy[i];
if(0<=tx && tx < SIZE && 0<=ty && ty < SIZE)t[tx][ty]=!t[tx][ty];
}
}
- Dec 18 Sat 2010 16:51
UVA 10309
全站熱搜
留言列表