zoukankan      html  css  js  c++  java
  • leetcode周赛 242

    A:水题,给定01串,问连续的0更长还是连续的1更长。

    直接遍历即可。

     1 class Solution {
     2 public:
     3     bool checkZeroOnes(string s) {
     4         int res1=0,res0=0;
     5         int cnt1=0,cnt0=0;
     6         for(int i=0;i<s.size();i++){
     7             if(s[i]=='1'){
     8                 res0=max(res0,cnt0);
     9                 cnt0=0;
    10                 cnt1++;
    11             }else if(s[i]=='0'){
    12                 res1=max(res1,cnt1);
    13                 cnt1=0;
    14                 cnt0++;
    15             }
    16         }
    17         res0=max(res0,cnt0);
    18         res1=max(res1,cnt1);
    19         return res1>res0;
    20     }
    21 };

    B:https://leetcode-cn.com/contest/weekly-contest-242/problems/minimum-speed-to-arrive-on-time/

    可以发现走完全程所需的时间随着速度的增加而减少(单调不增)

    故可以直接二分速度。计算当前速度所需的时间,同给定的时间进行比较。

    【注】速度是整数。

    考试时候的double+ceil写法:

     1 class Solution {
     2 public:
     3     const double eps=1e-8;
     4     double cal(vector<int>& dist,double speed){
     5         double res=0;
     6         int n=dist.size();
     7         for(int i=0;i<n-1;i++){
     8             res+=ceil(dist[i]/speed);
     9         }
    10         res+=dist[n-1]/speed;
    11         return res;
    12     }
    13     int minSpeedOnTime(vector<int>& dist, double hour) {
    14         int n=dist.size();
    15         double l=0,r=2e7;
    16         while(r-l>=eps){
    17             double mid=(l+r)/2;
    18             if(cal(dist,mid)<=hour) r=mid;
    19             else l=mid;
    20         }
    21         if(fabs(l-2e7)<eps)
    22             return -1;
    23         return ceil(l);
    24     }
    25 };

    可以写整数二分,而不用double(不用考虑精度问题)

     1 class Solution {
     2 public:
     3     double cal(vector<int>& dist,int speed){
     4         double res=0;
     5         int n=dist.size();
     6         for(int i=0;i<n-1;i++){
     7             res+=(dist[i]+speed-1)/speed;
     8         }
     9         res+=(double)dist.back()/speed;
    10         return res;
    11     }
    12     int minSpeedOnTime(vector<int>& dist, double hour) {
    13         int n=dist.size();
    14         int l=1,r=2e7;//l一定初始化为1,因为如果初始化为0的话,会出现除0的情况
    15         while(l<r){
    16             int mid=(l+r)/2;
    17             if(cal(dist,mid)<=hour) r=mid;
    18             else l=mid+1;
    19         }
    20         if(r==2e7)
    21             return -1;
    22         return r;
    23     }
    24 };

    C:跳跃游戏,一个点 i 能够跳到 j 的充要条件是 s [ j ] ='1' ,且 j >= i+minJump && j<=i+maxJump .

     这样的话,对于一个点也只能够从 j -maxJump ~ j - minJump 跳过来,故可以直接通过DP求解。

     考试时候写法:

     1 const int N=1e5+10;
     2 bool f[N];
     3 class Solution {
     4 public:
     5     bool canReach(string s, int minJump, int maxJump) {
     6         memset(f,0,sizeof f);
     7         int n=s.size();
     8         s=' '+s;
     9         f[1]=true;
    10         deque<int> q;
    11         q.push_back(1);
    12         for(int j=1;j<=s.size();j++){//对于j,它可以从j-maxjunp~j-minjump调过来
    13             while(q.size()&&q.front()<j-maxJump) q.pop_front();
    14             while(q.size()&&q.back()>j-minJump) q.pop_back();//这两个循环保证队列中的数是可以跳到j的
    15             if(j-minJump>=1&&f[j-minJump]) q.push_back(j-minJump);
    16             if(s[j]=='1') f[j]=false;
    17             else if(s[j]=='0'){
    18                 if(q.size())
    19                     f[j]=true;
    20             }
    21         }
    22         return f[n];
    23     }
    24 };

    考试错在没加第14行,比如“000000” minjump =4  maxjump=5 第二个字符就是不能被跳到的,但是少14行就不能把1弹出去。


    也可以用前缀和来记录1~i 区间内有多少个可以到的点,这样的话就可以在O(1)的时间内求出 j - maxJump ~ j - minJump是否有可以到达的点了。

     1 const int N=1e5+10;
     2 bool f[N];
     3 int sum[N];
     4 class Solution {
     5 public:
     6     bool canReach(string str, int a, int b) {
     7         
     8         memset(f,0,sizeof f);
     9         memset(sum,0,sizeof sum);
    10         int n=str.size();
    11         str=' '+str;
    12         f[1]=1;
    13         sum[1]=1;
    14         for(int i=2;i<=n;i++){
    15             sum[i]=sum[i-1];
    16             if(str[i]=='0'&&i-a>=1){
    17                 int r=i-a,l=max(1,i-b);
    18                 if(sum[r]-sum[l-1]>0){
    19                     f[i]=1;
    20                     sum[i]++;
    21                 }
    22             }
    23         }
    24         // for(int i=1;i<=n;i++) cout<<sum[i]<<" ";
    25         return f[n];
    26     }
    27 };

    D:因为是Alice先手,所以题目描述的Alice目标是使得P_Alice - P_Bob最大,而Bob目标是使得他最小,意思是Alice得分一定比Bob高。

     

     1 class Solution {
     2 public:
     3     int stoneGameVIII(vector<int>& stones) {
     4         int n=stones.size();
     5         vector<int> f(n);
     6         vector<int> pre(n+1);
     7         for(int i=1;i<=n;i++) pre[i]=pre[i-1]+stones[i-1];
     8         f[n-1]=pre[n];
     9         for(int i=n-2;i>=1;i--){
    10             f[i]=max(f[i+1],pre[i+1]-f[i+1]);
    11         }
    12         return f[1];
    13     }
    14 };
  • 相关阅读:
    用户身份与文件权限
    W3school——javascript笔记
    第十一章——常用的Web应用程序
    探究CBV视图
    Django objects.all()、objects.get()与objects.filter()之间的区别介绍
    RTX检索COM 类工厂出错
    Oracle存储过程实例
    Oracle返回数据集
    Oracle数据库创建表空间、创建表、授权
    JS传参出现乱码的种种分析
  • 原文地址:https://www.cnblogs.com/greenofyu/p/14806319.html
Copyright © 2011-2022 走看看