zoukankan      html  css  js  c++  java
  • Round A 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
    ",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
    ",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
    ",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
    ",t,ans);
    58  }
    59  return 0;
    60 }
    61 /**/
    View Code
  • 相关阅读:
    Java中@Override的作用
    微软面试题: LeetCode 152. 乘积最大子数组 出现次数:2
    微软面试题: LeetCode 300. 最长递增子序列 出现次数:2
    微软面试题: LeetCode 76. 最小覆盖子串 出现次数:2
    微软面试题:剑指 Offer 52. 两个链表的第一个公共节点 出现次数:2
    微软面试题: LeetCode 79. 单词搜索 出现次数:2
    微软面试题: LeetCode 39. 组合总和 出现次数:2
    微软面试题: LeetCode 151. 翻转字符串里的单词 出现次数:2
    微软面试题: LeetCode 415. 字符串相加 出现次数:2
    微软面试题: LeetCode 110. 平衡二叉树 出现次数:2
  • 原文地址:https://www.cnblogs.com/hyghb/p/12589843.html
Copyright © 2011-2022 走看看