boj 1338 simple game 先枚举行 然后对每一列再找 用到了不少位运算 另外数组要定义全局 局部数组不为0

地址:http://acm.scs.bupt.cn/onlinejudge/showproblem.php?problem_id=1338

1. 1<<k 把1左移k位 也是2的k次方

2. 数组问题 局部数组初始值可能不为0,全局变量初始值为了。局部数组a[20]可以用memset(a,0,20)置0.

3. 先枚举行翻转的情况n行有2的n次方状态 然后再找列。

 

Simple GameSubmit: 84   Accepted:27Time Limit: 1000MS  Memory Limit: 65535K

Description
Recently, little White fell in love with a simple game. It is an N*M area which is covered by bi-color plates on each point. The plate is white on one side and black on the other. Every time, he can either turn over all the plates in the same row or column, that is, change each plate’s upward side white to black, or black to white, according to its current state. Given you the current state of all the plates in the N*M field, please help little White calculate the maximum number of white-upward plates after properly times of turning.

Input
The first line is two integer N and M (1<=N, M<=15). Following N lines, each line consists of M numbers, either 0 or 1, separated by a single space, in which 0 means black-upward and 1 white-upward.

Output
A single integer, the maximum number of white-upward plates little White can get.

Sample Input

4 9
1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0


Sample Output

35


Source
Chiara

 

 

#include <stdio.h>
#include<iostream>
#define MAXN 16

 

int n, m;
int Line[MAXN];
// 行已经枚举,因此逐列处理即可
// 倘若该列1的个数小于0的个数,则该列需要反转
int GetMax(int Line[MAXN])
{
    int Result = 0;
    for (int i = 0; i < m; ++i)
    {
        int Total_1 = 0;
        int Total_0 = 0;

        for (int j = 0; j < n; ++j)
        {
            if (Line[j] & (1 << i))
            {
                ++Total_1;
            }
            else
            {
                ++Total_0;
            }
        }
        // 选个大的加进来即可,不用真的进行列反转
        Result += Total_1 > Total_0 ? Total_1 : Total_0;
    }
    return Result;
}


int main()
{

    int i, j, k;
    scanf("%d %d", &n, &m);
    for (i = 0; i < n; ++i)
    {
        for (j = 0; j < m; ++j)
        {
            scanf("%d", &k);
            Line[i] |= k << j;
        }
    }

    int Best = 0;   // 记录全局最优值
    int NewLine[MAXN];

    // 枚举行的翻转行为
    for (i = (1 << n) - 1; i >= 0; --i)
    {
        // 每一个二进制数都表示一个翻转状态
        // 该位为1表示该行需要翻转,该位为0表示该行不需要翻转
        for (j = 0; j < n; ++j)
        {
            if ((1 << j) & i)
            {
                NewLine[j] = ~Line[j];  // 反转该行
            }
            else
            {
                NewLine[j] = Line[j];   // 该行不需要反转
            }
        }
        k = GetMax(NewLine);
        if (k > Best)
        {
            Best = k;
        }
    }
    printf("%d/n", Best);
    system("pause");
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值