2019暑假牛客训练赛(补题及笔记)

第一场

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构成的矩形的面积大小。

扫描二维码关注公众号,回复: 6835837 查看本文章

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 }
View Code

F题:Partition problem

Q:给你 2*N 个人,每两个人之间都有一个竞争价值,所有人之间的竞争价值由二维数组表述出来。现在,让你将这些人分为2队,每队N 人,两队展开竞争;求能产生的最大竞争价值为多少?

理解题意:2*N 个人分成两队,同一队内的队友之间不产生竞争价值;一个队的一名成员,与另一队的每个成员之间都会计算一次竞争价值。

猜你喜欢

转载自www.cnblogs.com/Amaris-diana/p/11223337.html