题意
一个n*m大小的苹果园,现在可以在某几块地上施肥。施肥作用效果是使得上下左右的四个区域内结的苹果数量翻倍,但是施过肥的地就不能放果树了。求最多能收获多少苹果。
思路
贪心 + 规律
从第一排第一个开始施肥,每隔一个位置施肥。
第二排从第二个位置开始施肥,……
第三排从第一个位置开始施肥,……
……
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define mst(a) memset(a, 0, sizeof(a))
using namespace std;
const int maxn = 105;
int vis[maxn][maxn], a[maxn][maxn];
int turn[5][3] = {{1,0},{0,1},{-1,0},{0,-1}};
int n, m;
bool judge( int x, int y ){
if( x >= 0 && x < n && y >= 0 && y < m && !vis[x][y] ){
return true;
}
return false;
}
void change( int x, int y ){
int xx, yy;
for( int i = 0; i < 4; i++ ){
xx = x + turn[i][0], yy = y + turn[i][1];
if( judge( xx, yy ) ){
a[xx][yy] = a[xx][yy] * 2;
}
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n, &m);
if( n == 1 && m == 1 ){
printf("1
");
continue;
}
mst(vis);
mst(a);
int flag = 0;
for( int i = 0; i < n; i++ ){
for( int j = 0; j < m; j++ ){
if( (j+flag)%2 == 0 )
vis[i][j] = 1;
a[i][j] = 1;
}
flag = !flag;
}
for( int i = 0; i < n; i++ ){
for( int j = 0; j < m; j++ ){
if( vis[i][j] ){
change(i, j);
a[i][j] = 0;
}
}
}
int sum = 0;
for( int i = 0; i < n; i++ ){
for( int j = 0; j < m; j++ ){
//printf("%d ",vis[i][j]);
sum += a[i][j];
}
//printf("
");
}
printf("%d
", sum);
}
return 0;
}