第一场
E题:ABBA (类 卡特兰数)
Bobo有一个长度为2(n + m)的字符串,由字符“A”和“B”组成。该字符串还具有迷人的特性:它可以分解为(n+ m)个长度为2的子序列,并且在(n+ m)个子序列中,它们中的n个子序列为“AB”,而其他m个为“BA”。
Q:现在给出n 和m ,请问你,最多能找到多少个满足上述条件的串?
理解题意:题目中,分解为“子序列”,而非“子串”;就是说这个长度为2的子序列可以是不连续的。如BBABAA,这个串中有3个‘BA’。
第二场
H题:Second Large Rectangle(次大全1矩阵)
Q:给出一个N x M 的二进制矩阵,请输出第二大的全部由1构成的矩形的面积大小。
A:算出每个位置连续1的二维矩阵,单调栈。(补题:丁得宝)
1 #include<map> 2 #include<cmath> 3 #include<string> 4 #include<cstdio> 5 #include<cstring> 6 #include<iostream> 7 #include<algorithm> 8 #define inf 0x3f3f3f3f 9 using namespace std; 10 const int maxn = 1e3+5; 11 int sum[maxn][maxn],Stack[maxn],n,m; 12 int main() 13 { 14 string s; 15 while(~scanf("%d%d", &n, &m)) 16 { 17 memset(sum,0,sizeof(m)); 18 for(int i=1; i<=n; i++) 19 { 20 cin>>s; 21 for(int j=0; j<m; j++) 22 { 23 if(s[j]=='0') sum[i][j+1]=0; 24 else sum[i][j+1]=sum[i][j]+1; 25 } 26 } 27 int m1=0,m2=0; 28 Stack[0]=0; 29 for(int j=m; j>0; j--) 30 { 31 int top=0; 32 Stack[0]=0; 33 for(int i=1; i<=n; i++) 34 { 35 if(sum[i][j]>=sum[Stack[top]][j]) 36 Stack[++top]=i; 37 else 38 { 39 int len; 40 while(sum[i][j]<sum[Stack[top]][j]) 41 { 42 len=i-Stack[top-1]-1; 43 int s=sum[Stack[top]][j]*len; 44 if(s>m1) 45 { 46 m2=max(m1,sum[Stack[top]][j]*(len-1)); 47 m1=s; 48 } 49 else if(s==m1) 50 m2=m1; 51 else if(s>m2) 52 m2=s; 53 top--; 54 } 55 Stack[++top]=i; 56 } 57 } 58 for(int i=1; i<=top; i++) 59 { 60 int s=sum[Stack[i]][j]*(Stack[top]-Stack[i-1]); 61 if(s>m1) 62 { 63 m2=max(m1,sum[Stack[i]][j]*(Stack[top]-Stack[i-1]-1)); 64 m1=s; 65 } 66 else if(s==m1) 67 m2=m1; 68 else if(s>m2) 69 m2=s; 70 } 71 } 72 printf("%d\n",m2); 73 } 74 return 0; 75 }
Q:给你 2*N 个人,每两个人之间都有一个竞争价值,所有人之间的竞争价值由二维数组表述出来。现在,让你将这些人分为2队,每队N 人,两队展开竞争;求能产生的最大竞争价值为多少?
理解题意:2*N 个人分成两队,同一队内的队友之间不产生竞争价值;一个队的一名成员,与另一队的每个成员之间都会计算一次竞争价值。