您的位置:首页 > 其它

poj 2965

2013-12-14 20:01 260 查看
这题和1753题差不多,只不过多了一个记录每次走过的状态。所以重点还是在于怎么记录每次的状态,和怎么搜索、剪枝。下面是一个普通的方法,

BFS:

#include

#include

using namespace std;
typedef char flip[4][5] ;

flip a[67000] ;

typedef int bushu[16][2];

bushu b[67000];

int c[67000][2];
int fun(flip p , int i , int j , int rear)

{

 int k , n = 0 ;

 for( k = 0 ; k < 4 ; k++)

 {

  if(p[i][k] =='-')  p[i][k] = '+';

  else p[i][k] = '-';

 }

 for( k = 0 ; k < 4 ; k++)

 {

  if(k == i) continue;

  if(p[k][j] =='-')  p[k][j] = '+';

  else p[k][j] = '-';

 }

 for(k = 0; k < 4 ;k ++)

 {

  for(int g = 0 ; g < 4 ;g++)

   if(p[k][g] =='-')  n += 1;

 }

 if(n == 16)

 

 // for(k = 0 ; k < 4 ;k++)

 //  cout<<p[k]<<endl;

  return rear;

 

 else return 0;

}
int main()

{

 int i = 0, j = 0 , k = 0 , n = 0;

 

 for(i = 0 ; i < 4 ; i ++)

 {

  cin>>a[0][i];

  for(j = 0 ; j < 4 ; j++)

   if(a[0][i][j]== '-')  n += 1;

 }

 if(n == 16) {cout<<0<<endl; return 0;}

 n = 0;

 flip p ;

 for(i = 1 ; i <= 16 ; i++)

 {

 

  for( k = 0 ; k < 4 ; k++)

  {

   strcpy(p[k] ,a[0][k]); 

  }

  n = fun(p , (i-1)/4 , (i-1)%4 ,i);

  b[i][0][0] = (i-1)/4;

  b[i][0][1] = (i-1)%4;

  c[i][0] = i-1;

  c[i][1] = 1;

  if(n > 0 ) break;

  for(k = 0 ; k < 4 ; k++)

  {

   strcpy(a[i][k],p[k]);

  // cout<<p[k]<<endl;

  }

 // cout<<endl;

 }

 if(n >0)

 {

  cout<<1<<endl;

  cout<<(b
[0][0]+1)<<""<<(b
[0][1]+1)<<endl;

  return 0;

 }

 int m = 0 ;

 int front = 1 , rear = 17;

 while(front < rear)

 {

  int x = c[front][0] , y =c[front][1]; // cout<<y<<endl;

  for(i = x+1 ; i < 16 ;i++)

  {

   for(j = 0 ; j< 4 ;j++)

    strcpy(p[j], a[front][j]);

   m = fun(p ,i/4 , i%4 , rear);

   for(j = 0 ; j< y; j++)

   {

    b[rear][j][0]= b[front][j][0];

    b[rear][j][1]= b[front][j][1];

   }

   b[rear][y][0]= i/4;

   b[rear][y][1]= i%4;

   c[rear][0] =i;

   c[rear][1] =y + 1;

   if(m >0)  break;

   for(j = 0 ; j< 4 ;j++)

    strcpy(a[rear][j], p[j]);

   rear +=1;

  }

  if(m > 0) break;

  front += 1;

//  cout<<rear<<endl;

 }

//if(m > 0)

// {

  cout<<c[m][1]<<endl;

  for(i = 0 ; i < c[m][1];i++)

  cout<<(b[m][i][0]+1)<<""<<(b[m][i][1]+1)<<endl;

// }

// elsecout<<"Impossible"<<endl;

// cout<<a[0][1];

 return 0;

}

 

分割线

 

下面这个代码是大牛写的,真牛

1、这里先有一个关键点,怎么样让一个位置的+变成-并且不改变和其相关联的位置的状态?这是关键所在

那就是使和其相关联的位置各改变一次,包括其自己,这样就只改变了该位置的状态。

2、对于每个位置的+都这样改变。然后用一个4*4的数组来记录改变的次数,即每个位置改变一次,就在数组中的该位置+1;这样当该位置的数为偶数时,也就是没有改变,因此只要搜索数组中有多少个奇数。

 

#include

#include

using namespace std;

char a[4][5] ;

int jilu[4][4] ;

int main()

{

 int i , j ;

 for(i = 0 ; i < 4 ; i ++)

  cin>>a[i];

 memset(jilu , 0 , sizeof(jilu));

 for(i = 0; i< 4 ; i ++)

  for(j = 0 ; j < 4 ; j++)

  {

   if(a[i][j] =='+')

   {

    intk = 0;

    for(k= 0 ; k < 4 ; k++)

     jilu[i][k]+= 1;

    for(k= 0 ; k < 4 ; k ++)

    {

     if(k== i)  continue;

     jilu[k][j]+= 1;

    }

   }

  }

 int n = 0 ;

 for(i = 0 ; i < 4 ; i ++)

  for(j = 0 ; j < 4 ; j++)

   if(jilu[i][j]%2!= 0)   n += 1;

 cout<<n<<endl;

 for(i = 0 ; i < 4 ; i ++)

  for(j = 0 ; j < 4 ; j++)

   if(jilu[i][j]%2!= 0)  cout<<(i+1)<<" "<<(j+1)<<endl;

 return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: