好玩的木桩
Time Limit: 2000/1000ms (Java/Others)
Problem Description:
一天,小明来到一个农场,看到农场上有许许多多的木桩,这些木桩被摆成一个m*n的矩阵,而且木桩的长度只有两种,那么我们用1来表示长木桩,0表示短木桩,小明突然想到一个好玩的事情:如果我们能移动矩阵的行,问最大可以得到全是长木桩(都是1)矩阵的面积。
Input:
第一行,输入两个数m,n,(0<m,n<=5000); 然后输入m*n大小的0,1矩阵。
Output:
最大可以得到全是长木桩(都是1)矩阵的面积。对于每组数据,输出答案,占一行。
Sample Input:
4 3 100 011 000 101
Sample Output:
2
思路:先写出每行的每列向左延伸的最大值,如01111就是01234;此后,再对每列进行排序(从小到大),这样就能保证上面的都能被下面的拓展。本题还有个关键点,如何对二维数组的列进行排序?(这个可以转换下思维)
附上AC代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
int n;
while(cin >> n){
while(n--)
{
ll l,r;
cin >> l >> r;
int rr[100];
int ll1[100];
memset(rr,0,sizeof(rr));
memset(ll1,0,sizeof(ll1));
int s = 0;
int s2 = 0;
ll r1 = r;
while(r)
{
if(r&1)
rr[s++] = 1;
else
rr[s++] = 0;
r>>=1;
}
while(l)
{
if(l&1)
ll1[s2++] = 1;
else
ll1[s2++] = 0;
l>>=1;
}
int maxx = max(s,s2);
int f = -1;
ll sum = 0;
for(int i = maxx-1;i >= 0;i--)
{
if(ll1[i] != rr[i])
{
f = i;
break;
}
else if(ll1[i] == 1)
sum+=(ll)(pow(2,i)+0.5);
}
ll x = 1;
if(f == -1)
cout << r1 <<endl;
else
{
f++;
while(f--)
{
sum+=x;
x<<=1;
}
cout << sum <<endl;
}
}}
return 0;
}