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 };

 

posted on 2021-05-24 21:39  greenofyu  阅读(40)  评论(0编辑  收藏  举报