topcoder SRM400 div2 1000point(pass system test)

来源:互联网 发布:海湾主机编程 编辑:程序博客网 时间:2024/05/16 15:05

 

#include<iostream>
#include
<stdlib.h>
#include
<vector>
#include
<sstream>
#include
<string>
#include
<math.h>
#include
<algorithm>
using namespace std;

class LightedPanels
{
    
public:
        
int minTouch(vector <string> board);
}
;

int m2(int w)
{
    
int a = 1;
    
for(int i = 0;i<w;i++)
        a 
*= 2;
        
return a;
}


bool check(int **t,int w,int i)
{
    
for(int a = 0;a<w;a++)
        
if(t[i][a] != 1)
            
return false;
    
return true;
}



void toggle(int **t,int **tmp,int w,int h,int i,int mask)
{
    
int test(0);
    
int a(0);
    
int l(0);
    
int b(0);
    
    
for(int x = 0;x<h;x++)
    
for(int j = 0;j<w;j++)
        tmp[x][j] 
= t[x][j];
    
    
for(l = 0;l<w;l++)
    
{
        test 
= (mask>>l)& 0x00000001;
        
if(test == 1)
        
{
            
for(a = i-1;a<i+2;a++)
            
{
                
for(b = w-l-2;b<w-l+1;b++)
                    
{
                        
if(!(a<0 || a==|| b<0||b==w))
                        tmp[a][b] 
= 1-tmp[a][b];
                    }

            }

        }

    }

}


int ff(int **t ,int w,int h)
{
    
int min(w+1);
    
int i(0);
    
int j(0);
    
int l(0);
    
int row(0);
    
int m2w = m2(w);
    
int res(0);
    
int mask(0);
    
int none(0);
    
    
int **tmp1 = new int*[h];
    
for(i = 0;i<h;i++)
        tmp1[i] 
= new int[w];
        
    
int **tmp = new int*[h];
    
for(i = 0;i<h;i++)
        tmp[i] 
= new int[w];
        
    
for(i = 0;i<h;i++)
    
for(j = 0;j<w;j++)
        tmp1[i][j] 
= t[i][j];
    
    
for(i = 1;i<h;i++)
    
{
        
for(l = 0;l<m2w;l++)
        
{
            toggle(tmp1,tmp,w,h,i,l);        
            
if(check(tmp,w,i-1))
            
{
                
for(j = 0;j<w;j++)
                    row 
+= (l>>j)& 0x00000001;
                
if(row<min)
                
{
                    min 
= row;
                    mask 
= l;
                }

            }

            row 
= 0;
        }

        
if(min != w+1)                //find a answer
        {
            res 
+= min;
            toggle(tmp1,tmp1,w,h,i,mask);
            mask 
= 0;
            min 
= w+1;
        }
            
        
else                    //can't find a answer
        {
            none 
= 1;
        }

        
    }

    
if(!check(tmp1,w,h-1))        //the last row 
    {
        none 
= 1;
     }

     
for(i = 0;i<h;i++)
     delete [] tmp1[i];
     delete [] tmp1;
      
for(i = 0;i<h;i++)
     delete [] tmp[i];
     delete [] tmp;
     
     
if(none == 1)
         
return -1;
     
else
         
return res;
     
}

    
    
int LightedPanels::minTouch(vector <string> board)
{
    
int i(0),j(0);
    
int w = board[0].size();
    
int h = board.size();
    
int m2w = m2(w);
    
int **= new int*[h];
    
for(i = 0;i<h;i++)
        t[i] 
= new int[w];
        
    
int **tmp = new int*[h];
    
for(i = 0;i<h;i++)
        tmp[i] 
= new int[w];
        
    
for(i = 0;i<h;i++)
    
{
        
for(j = 0;j<w;j++)
        
{
            
if((board[i].c_str())[j] == '*')
                t[i][j] 
= 1;
            
else
                t[i][j] 
= 0;
        }

    }

            
    
for(i = 0;i<h;i++)
    
{
        
for(j = 0;j<w;j++)
        cout
<<t[i][j]<<",";
        cout
<<endl;
    }

    
    
int count(0);
    
int min(65);
    
for(i = 0;i<m2w;i++)
    
{
        cout
<<"..........i....."<<i<<endl;
        toggle(t,tmp,w,h,
0,i);
        count 
= ff(tmp,w,h);
        
if(count != -1)
        
{
            
for(int l = 0;l<w;l++)
                count 
+= (i>>l)& 0x00000001;
            
if(count < min)
            min 
= count;
        }

    }

    
if(min == 65)
        
return -1;
    
else
         
return min;
}


/*        for(int ti = 0;ti<h;ti++)
                {
                for(int tj = 0;tj<w;tj++)
                cout<<t[ti][tj]<<",";
                cout<<endl;
                }
*/