Round A 2020 - Kick Start 2020

Allocation
题意:n(1e5)个数,选出尽可能多的数使他们总和小于等于b。
思路:排序,尽可能取小。
 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 #define dl double
 4 void rd(int &x){
 5  x=0;int f=1;char ch=getchar();
 6  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 7  while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f;
 8 }
 9 void lrd(LL &x){
10  x=0;int f=1;char ch=getchar();
11  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12  while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f;
13 }
14 const int INF=1e9;
15 const LL LINF=1e18;
16 const int N=1e5+10; 
17 using namespace std;
18 int T,n,a[N],b;
19 int main(){
20 // freopen("in.txt","r",stdin);
21  rd(T);
22  for(int t=1;t<=T;t++){
23   rd(n);rd(b);
24   for(int i=1;i<=n;i++)rd(a[i]);
25   sort(a+1,a+n+1);int mx=0;
26   for(int i=1;i<=n;i++){
27    b-=a[i];
28    if(b >= 0)mx=i;
29    else break;
30   }
31   printf("Case #%d: %d\n",t,mx);
32  }
33  return 0;
34 }
35 /**/
View Code
Plates
题意:n(50)组数字,每组k(30)个,选出p个数,使得和最大,如果要选择一个数字就必须选择其所在组中它前面的所有数字。
思路:fij表示前i组,一共选了j个数最大值是多少,每个fij枚举当前组取前多少个数字更新答案。
 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 #define dl double
 4 void rd(int &x){
 5  x=0;int f=1;char ch=getchar();
 6  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 7  while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f;
 8 }
 9 void lrd(LL &x){
10  x=0;int f=1;char ch=getchar();
11  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12  while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f;
13 }
14 const int INF=1e9;
15 const LL LINF=1e18;
16 const int N=55;
17 const int K=35;
18 using namespace std;
19 int T,n,k,p;
20 int f[N][N*K];
21 int a[N][K];
22 int main(){
23 // freopen("in.txt","r",stdin);
24  rd(T);
25  for(int t=1;t<=T;t++){
26   rd(n);rd(k);rd(p);
27   for(int i=1;i<=n;i++)
28    for(int j=1;j<=k;j++)
29     rd(a[i][j]);
30   memset(f,0,sizeof(f));
31   for(int i=0;i<n;i++){
32    int now=0;
33    for(int j=0;j<=k;j++){
34     now+=a[i+1][j];
35     int tmp=min(i*k,p);
36     for(int o=0;o<=tmp;o++)
37      f[i+1][o+j]=max(f[i+1][o+j],f[i][o]+now);
38    }
39   }
40   int mx=0;
41   for(int i=0;i<=p;i++)mx=max(mx,f[n][i]);
42   printf("Case #%d: %d\n",t,mx);
43  }
44  return 0;
45 }
46 /**/
View Code

Workout

题意:给n(1e5)个正整数,在其中插入k个正整数,使得相邻两数之差绝对值的最大值最小,输出这个值是多少。

思路:发现如果k个数可以做到,k+1个数也可以做到,具有单调性,不妨二分答案,判断过程记录每两个数之间至少插入数的个数。需要注意我的写法中二分部分对于判断0时会出现问题,所以二分下限设成了1,0的情况只能是所有数字都相同的情况,特殊判断即可。

 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 #define dl double
 4 void rd(int &x){
 5  x=0;int f=1;char ch=getchar();
 6  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 7  while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f;
 8 }
 9 void lrd(LL &x){
10  x=0;int f=1;char ch=getchar();
11  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12  while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f;
13 }
14 const int INF=1e9;
15 const LL LINF=1e18;
16 const int N=1e5+10;
17 using namespace std;
18 int T;
19 int n,k,a[N];
20 bool check(int x){
21  int now=k;
22  for(int i=1;i<n;i++){
23   int tmp1=a[i+1]-a[i];
24   int tmp2=(tmp1+x-1)/x;
25   now-=tmp2-1;
26   if(now < 0)return 0;
27  }
28  return 1;
29 }
30 int main(){
31 // freopen("in.txt","r",stdin);
32  rd(T);
33  for(int t=1;t<=T;t++){
34   rd(n);rd(k);
35   for(int i=1;i<=n;i++)rd(a[i]);
36   int l=1,r=1e9;
37   while(l != r){
38    int mid=l+r>>1;
39    if(check(mid))r=mid;
40    else l=mid+1;
41   }
42   bool flg=0;
43   for(int i=1;i<n;i++)if(a[i]!=a[i+1])flg=1;
44   if(!flg)l=0;
45   printf("Case #%d: %d\n",t,l);
46  }
47  return 0;
48 }
49 /**/
View Code
Bundling
题意:n(1e5)个字符串,每k(n%k==0)个分为一组,每组权值为组内元素最大公共前缀的长度,求所有组权值和的最大值是多少。
思路:trie树上dfs,一旦当前点子树大小超过了k就将这k个分为一组,贪心即可。
 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 #define dl double
 4 void rd(int &x){
 5  x=0;int f=1;char ch=getchar();
 6  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 7  while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f;
 8 }
 9 void lrd(LL &x){
10  x=0;int f=1;char ch=getchar();
11  while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12  while(ch<='9' && ch>='0')x=x*10+ch-'0',ch=getchar();x*=f;
13 }
14 const int INF=1e9;
15 const LL LINF=1e18;
16 const int N=1e5+10;
17 using namespace std;
18 int T,n,k,ans;
19 int ch[N*20][26],tot,siz[N*20],dep[N*20];
20 string s;
21 void clear(){
22  for(int i=0;i<=tot;i++){
23   siz[i]=0;dep[i]=0;
24   for(int j=0;j<26;j++)
25    ch[i][j]=0;
26  }
27  tot=0;ans=0;
28 }
29 void insert(string s){
30  int len=s.size(),now=0;
31  for(int i=0;i<len;i++){
32   if(!ch[now][s[i]-'A'])ch[now][s[i]-'A']=++tot;
33   now=ch[now][s[i]-'A'];
34  }
35  siz[now]++;
36 }
37 void dfs(int x){
38  for(int i=0;i<26;i++){
39   if(!ch[x][i])continue;
40   dep[ch[x][i]]=dep[x]+1;
41   dfs(ch[x][i]);
42   siz[x]+=siz[ch[x][i]];
43   if(siz[x] >= k)ans+=dep[x]*(siz[x]/k),siz[x]%=k;
44  }
45  if(siz[x] >= k)ans+=dep[x]*(siz[x]/k),siz[x]%=k;
46 }
47 int main(){
48 // freopen("in.txt","r",stdin);
49  rd(T);
50  for(int t=1;t<=T;t++){
51   rd(n);rd(k);clear();
52   for(int i=1;i<=n;i++){
53    cin>>s;
54    insert(s);
55   }
56   dfs(0);
57   printf("Case #%d: %d\n",t,ans);
58  }
59  return 0;
60 }
61 /**/
View Code

 

posted @ 2020-03-28 22:19  hyghb  阅读(175)  评论(0编辑  收藏  举报