基于组合的分田地

题目描述:

洋洋和15个朋友来玩打土豪分田地的游戏,洋洋决定让你来分田地,地主的田地可以看成是一个矩形,每个位置有一个价值,分割田地的方法是横竖各切三刀,分成16份,作为领导干部,洋洋总是会选择其中价值最小的一份田地,作为洋洋最好的朋友,你希望洋洋取得的田地价值和尽可能大,你知道这个值最大可以是多少吗?


输入描述:

每个输入包含1个测试用例。每个测试用例的第一行包含两个整数n和m(1 <=n, m <= 75),表示田地的大小,接下来的n行,每行包含m个0-9之间的数字,表示每块位置的价值。


输出描述:

输出一行表示洋洋所取得的最大的价值。


输入例子:

4 4

3332

3233

3332

2323

输出例子:

2


分析:是考察组合

代码:

#include <iostream>  
#include <vector>  
#include <cstdio>  
#include <string>  
#include <algorithm>  
#include <climits>  
  
  
using namespace std;  
  
  
bool compare(const char &lhs, const char& rhs)  
{  
    return lhs > rhs;  
}  
  
bool combination(string &wk)  
{  
    size_t found = string::npos;  
  
    if( (found=wk.find("10"))!=string::npos )  
    {  
        // 1. swap found  
        wk[found] = '0';  
        wk[found+1] = '1';  
  
          
        // 2. sort before  
        sort(wk.begin(), wk.begin()+found, compare);  
  
        return true;  
  
    }  
    else  
        return false;  
}  
  
  
int main(int argc, char** argv[])  
{  
    int n, m;  
    while(cin >> n >> m)  
    {  
        vector< vector<int> > A(n, vector<int>(m, 0));  
        vector< vector<int> > iA(n+1, vector<int>(m+1,0));    // the integral image  
        for(int i=0; i<n; i++)  
        {   
            for(int j=0; j<m; j++)  
            {  
                scanf("%1d", &A[i][j]);  
                iA[i+1][j+1] = iA[i+1][j] + iA[i][j+1] - iA[i][j] + A[i][j];  
            }  
        }  
  
        // generate the combination  
        if(n < 4 || m < 4)  
        {  
            cout << 0 << endl;  
            continue;   
        }  
          
        int maxs = 0;  
        string nk = string(3, '1') + string(n-3-1,'0'); // there is only n-1 intervals    
        int npos[5];  
        int mpos[5];  
        npos[0] = 0;  
        npos[4] = n;  
        mpos[0] = 0;  
        mpos[4] = m;  
        do{  
            size_t nfound = -1;  
            for(int i=0; i<3; i++)  
            {  
                nfound = nk.find('1', nfound+1);  
                npos[i+1] = nfound+1; //   
            }  
  
            // the m  
			string mk = string(3, '1') + string(m-3-1,'0');  
            do{  
                size_t mfound = -1;  
                for(int i=0; i<3; i++)  
                {  
                    mfound = mk.find('1', mfound+1);  
                    mpos[i+1] = mfound+1;  
  
                }  
  
                // one devide the field  
                int mins = INT_MAX;  
  
                for(int i=0; i<4; i++)  
                {  
                    for(int j=0; j<4; j++)  
                    {  
                        int f = iA[npos[i+1]][mpos[j+1]] - iA[npos[i+1]][mpos[j]] - iA[npos[i]][mpos[j+1]] + iA[npos[i]][mpos[j]];  
                        mins = min(mins, f);  
                    }  
                }  
  
                maxs = max(maxs, mins);  
  
            } while(combination(mk));  
  
        } while(combination(nk));  
  
  
        cout << maxs << endl;  
              
    }  
  
    return 0;  
}

 

结果如下:


代码没有做更多的测试,也不知道程序对不对,难过,欢迎大家指正错误




后记:

这样输入进来的是转换成了ASCII码,相当于输入进来的是字符型:

第一种情况:


输出:其中51是3的ASCII码,


第二种情况:


输出:竟然也能把换行输出来了,且iA中保存的就是想要的数。


第三种情况,改为int保存,也没有啥问题


输出:



参考:

【1】组合算法(C++ 实现) http://liam0205.me/2016/01/31/binomial-in-cpp/

【2】heap corruption detected错误解决方法调试方法以及内存管理相关 http://blog.sina.com.cn/s/blog_622bd16601018zzu.html

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值