• aoj0525


    一、题意:题目大致是讲一个烧饼铺烤烧饼,在一个n X m (1<=n<=10,1<=m<=10000)的烤桌上面摆着一堆烧饼,数字1表示烧饼正面,0表示烧饼反面。然后你每次可以将一整行或者一整列的烧饼翻面,即正面翻成反面或者反面翻成正面。但是必须是一整列或者一整行的翻,问最多可以使都少烧饼翻成正面?题意还是很好懂的。

    二、思路:由于n比较小,所以可以对行DFS,那列呢?其实列很好处理,对每一列统计1的个数或者0的个数,保留最大者即是最大的正面个数,试想如果当前列正面个数多,那这一列就不翻面就好了,如果反面多,那么将该列翻面即可使得原先反面变成正面。所以对列直接统计即可。这题需要注意的是无论哪一行或者那一列先翻面都是无谓的,不影响结果,即翻面的顺序不影响结果,只考虑该行或该列是否要翻面即可,所以可以直接DFS。输入数据的第一行表示n和m,接下来的n X m的0和1的矩阵就表示当前烧饼状态,输入0 0结束。总而言之,此题很暴力。

    三、代码:

    #include"iostream"
    #include"stdio.h"
    #include"algorithm"
    #include"vector"
    #include"queue"
    using namespace std;
    
    int r,c;
    int maze[15][10005];
    int maxRes;
    
    void Rev(int n)
    {
        for(int j=0;j<c;j++)
            maze[n][j]=maze[n][j]^1;
    }
    
    int Cal()
    {
        int sum=0;
        for(int j=0;j<c;j++)
        {
            int cnt=0;
            for(int i=0;i<r;i++)
            {
                cnt+=maze[i][j];
            }
            sum+=max(cnt,r-cnt);
        }
        return sum;
    }
    
    void Dfs(int n)
    {
        if(n==r)
        {
            maxRes=max(maxRes,Cal());
            return;
        }
        Rev(n);
        Dfs(n+1);
        Rev(n);
        Dfs(n+1);
    }
    
    int main()
    {
     //   freopen("in.txt","r",stdin);
        while(scanf("%d%d",&r,&c)==2,r&&c)
        {
            maxRes=0;
            for(int i=0;i<r;i++)
            {
                for(int j=0;j<c;j++)
                    scanf("%d",&maze[i][j]);
            }
            Dfs(0);
            cout<<maxRes<<endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    cd的使用
    转换器模式
    装饰模式
    策略模式
    模板方法模式
    工厂模式
    类型信息
    proto编译组件使用
    proto编译引用外部包问题
    Kafka经典三大问:数据有序丢失重复
  • 原文地址:https://www.cnblogs.com/acm-jing/p/9606520.html
Copyright © 2020-2023  润新知