SRM 623 DIV2 1000pt
题意:给出一个最多50*50的矩阵,每个单元可能为'.'、'P'、'A','.'代表空地,你每次操作可以把一个P或者A拿到空地上,求一个最大的含有相同字符的矩形面积,最多K次操作。
首先用一个数组预处理出所有矩形所包含这三种字符的数量,然后枚举每一个矩形,如果只含有相同字符,那么这个面积是可以取到的。
如果含有多种字符,枚举含哪种字符时所需操作最少,大矩阵内如果含有一个及以上空地并且这个矩形的面积是小于等于你当前枚举的字符的数量,操作数=矩形内空地数+令一字符数*2
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 100000 12 #define LL long long 13 #define INF 0xfffffff 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 18 int s[65][65][3]; 19 class ApplesAndPears 20 { 21 public: 22 int getArea(vector <string> board, int K) 23 { 24 int n = board.size(); 25 int m = board[0].size(); 26 int i,j,g,e; 27 memset(s,0,sizeof(s)); 28 int a = 0,b = 0,c = 0; 29 for(i = 0; i < n ; i++) 30 for(j = 0; j < m; j++) 31 { 32 s[i+1][j+1][0] = s[i][j+1][0]+s[i+1][j][0]-s[i][j][0]; 33 s[i+1][j+1][1] = s[i][j+1][1]+s[i+1][j][1]-s[i][j][1]; 34 s[i+1][j+1][2] = s[i][j+1][2]+s[i+1][j][2]-s[i][j][2]; 35 if(board[i][j]=='.') 36 { 37 a++; 38 s[i+1][j+1][0]+=1; 39 } 40 else if(board[i][j]=='A') 41 { 42 b++; 43 s[i+1][j+1][1]+=1; 44 } 45 else 46 { 47 c++; 48 s[i+1][j+1][2]+=1; 49 } 50 } 51 int ans = 0; 52 for(i = 1 ; i <= n ; i++) 53 { 54 for(j = 1 ; j <= m ; j++) 55 { 56 for(g = 1 ; g <= i ; g++) 57 for(e = 1; e <= j ; e++) 58 { 59 int k1 = s[i][j][0]-s[g-1][j][0]-s[i][e-1][0]+s[g-1][e-1][0]; 60 int k2 = s[i][j][1]-s[g-1][j][1]-s[i][e-1][1]+s[g-1][e-1][1]; 61 int k3 = s[i][j][2]-s[g-1][j][2]-s[i][e-1][2]+s[g-1][e-1][2]; 62 63 int area = (i-g+1)*(j-e+1); 64 int res1 = area-k1; 65 if(k1==area||k2==area||k3==area) 66 { 67 ans = max(area,ans); 68 continue; 69 } 70 if(area<=a&&K>=res1) ans = max(ans,area); 71 res1 = area-k2; 72 int res2 = res1-k1; 73 if(area<=b&&a&&res2+res1<=K) ans = max(ans,area); 74 res1 = area-k3; 75 res2 = res1-k1; 76 if(area<=c&&a&&res2+res1<=K) ans = max(ans,area); 77 } 78 } 79 } 80 return ans; 81 } 82 };