POJ 1222

POJ 1222 结题报告(枚举和高斯)

这题可以用简单的方法求解,先穷举第一行的按键情况。然后一行一行关掉(做的时候看错题意,以为点亮,错了很久,所以一定要看清楚题意)前一排的灯。下面是代码,应该比较清晰。

#include <cstdio>
#include <cstring>

using std::memset;

int mapback[5][6];
int map[5][6];
int press[5][6];

void flip(int i,int j)
{
	map[i][j] = !map[i][j];
	if(i > 0) map[i-1][j] = !map[i-1][j];
	if(j > 0) map[i][j-1] = !map[i][j-1];
	if(i < 4) map[i+1][j] = !map[i+1][j];
	if(j < 5) map[i][j+1] = !map[i][j+1];
	return;
}

void swapfirstrow(int swapkey)
{
	int index = 0;
	while(swapkey)
	{
		if(swapkey%2)
		{
			press[0][index] = 1;
			flip(0,index);
		}
		swapkey /= 2;
		index++;
	}
}

bool solve()
{
	for(int i = 1; i < 5; i++)
	{
		for(int j = 0 ; j < 6; j++)
		{
			if(map[i-1][j] == 1)
			{
				press[i][j] = 1;
				flip(i,j);
			}
		}
	}

	for(int i = 0 ; i < 6; i++)
		if(map[4][i] == 1)
			return false;
	return true;
}

void print()
{
	for(int i = 0 ; i < 5; i++)
	{
		for(int j = 0 ; j < 5; j++)
		{
			printf("%d ", press[i][j]);
		}
		printf("%d\n", press[i][5]);
	}

	//printf("\n");
	//for(int i = 0 ; i < 5; i++)
	//{
	//	for(int j = 0 ; j < 5; j++)
	//	{
	//		printf("%d ", map[i][j]);
	//	}
	//	printf("%d\n", map[i][5]);
	//}
}

int main()
{
	int cas;
	scanf("%d", &cas);
	for(int casindex = 0 ; casindex < cas; casindex++)
	{
		for(int i = 0 ; i < 5; i++)
		{
			for(int j = 0 ; j < 6; j++)
				scanf("%d", &mapback[i][j]);
		}

		for(int i = 63 ; i >= 0; i--)
		{
			memcpy(map, mapback, sizeof(mapback));
			memset(press, 0, sizeof(press));

			swapfirstrow(i);

			if(solve())
			{
				printf("PUZZLE #%d\n", casindex+1);
				print();

				break;
			}
		}
	}
}

 

 

下面会写下高斯消元的解法,详细思路可移步至 http://blog.csdn.net/shiren_Bod/article/details/5766907

注意的地方:

1. 矩阵中的乘法转换为^

2. 矩阵中的加法运算后mod2(结合性质“同一个位置翻两次等于不翻”)。

3. 注意guass消元中的细节问题,比如换行之后要将rowindex重置(在这份代码中rowindex表示当前操作行)。

4. 这个问题中不会出现多解(因为秩为30,discuss中有人说有多解。。),所以不用判断(rowindex !=-1)也行。


#include <cstdio>
#include <cstring>

using std::memset;

const int MAX = 30;

int map[MAX][MAX+1];
int ans[MAX];

void swap(int &a, int &b)
{
    int t = a;
    a = b;
    b = t;
    return;
}

void guass(int nrows, int ncols)
{
    for(int row = 0, col = 0 ; row < nrows && col < ncols; col++)
    {
        //deal with i th column
        //find the row;
        int rowindex = -1;

        for(int i = row ; i < nrows; i++)
        {
            if(map[i][col])
            {
                rowindex = i;
                break;
            }
        }

        if(rowindex != -1){

            //swap to this row
            if(rowindex != row)
            {
                for(int i = 0 ; i < ncols; i++)
                swap(map[row][i], map[rowindex][i]);
            }

            rowindex = row;

            //elimate the rows
            for(int i = 0; i < nrows; i++)
            {
                if(i != rowindex && map[i][col])
                for(int j = col; j < ncols; j++)
                {
                    map[i][j] ^= map[rowindex][j];
                }
            }
            row++;
        }
    }

    //for(int i = 0 ; i < MAX; i++)
    //{
    //    for(int j = 0 ; j < MAX; j++)
    //    printf("%d", map[i][j]);
    //    printf(" %d\n", map[i][MAX]);
    //}


    //for(int i=0; i < MAX; i++)      //求出结果;
    //{
    //    if(map[i][MAX])
    //    {
    //        int j;
    //        for(j=0; j<30 && !map[i][j]; j++)  ;
    //        if(j == 30)
    //            return ;
    //        else
    //            ans[j] = map[i][30];
    //    }
    //}
}

int dx[5] = {0,0,0,1,-1};
int dy[5] = {0,1,-1,0,0};

int main()
{
    int cas;
    scanf("%d", &cas);
    for(int casindex = 0 ; casindex < cas; casindex++)
    {
        memset(map, 0, sizeof(map));
        memset(ans, 0, sizeof(ans));

        for(int i = 0 ; i < MAX; i++)
        {
            int x = i/6;
            int y = i%6;

            for(int j = 0 ; j < 5; j++)
            {
                int x1 = x + dx[j];
                int y1 = y + dy[j];

                if(0 <= x1 && x1 < 5 && 0 <= y1 && y1 < 6)
                {
                    map[i][x1*6+y1] = 1;
                }
            }
        }

        for(int i = 0 ; i < MAX; i++)
        scanf("%d", &map[i][MAX]);

        /*for(int i = 0 ; i < MAX; i++)
        {
            for(int j = 0 ; j < MAX; j++)
            printf("%d", map[i][j]);
            printf("\n");
        }*/

        guass(MAX, MAX+1);

        printf("PUZZLE #%d\n", casindex+1);
        for(int i = 0 ; i < 5; i++)
        {
            for(int j = 0 ; j < 6; j++)
            printf("%d ", map[i*6+j][MAX]);
            printf("\n");
        }
    }
}



 

posted @ 2013-07-03 13:39  little_hsu  阅读(227)  评论(0编辑  收藏  举报