• leetcode周赛 231


    A:水题。

    解法1:首先确定一个全为1的串,之后如果在出现1,就返回false

     1 class Solution {
     2 public:
     3     bool checkOnesSegment(string s) {
     4         bool flag=true;
     5         int n=s.size();
     6         for(int i=0;i<n;){
     7             if(s[i]=='1'&&flag){
     8                 while(s[i]=='1'){
     9                     i++;
    10                 }
    11                 flag=false;
    12                 continue;
    13             }else if(s[i]=='1'&&!flag) return false;
    14             i++;
    15         }
    16         return true;
    17     }
    18 };

    解法2:直接找到最前面的1和最后面的1,若中间的字符串被0分割开来的话,返回false

     1 class Solution {
     2 public:
     3     bool checkOnesSegment(string s) {
     4         int i=0,j=s.size()-1;
     5         while(s[i]=='0') i++;
     6         while(s[j]=='0') j--;
     7         for(int k=i;k<=j;k++) if(s[k]=='0') return false;
     8         return true;
     9     }
    10 };

    B:水题。给定一个数组,和一个goal,要求数组和等于goal,可以向数组内插入元素,但是插入元素x满足,abs(x)<limit;

     ans=abs(sum-goal+limit-1)/limit ; 

    1 class Solution {
    2 public:
    3     int minElements(vector<int>& nums, int limit, int goal) {
    4         long long sum=accumulate(nums.begin(),nums.end(),0ll);
    5         return (abs(sum-goal)+limit-1)/limit;
    6     }
    7 };

    C:题目很复杂,但是思路比较简单。

    给定一张联通图,受限路径定义为从1到n中每一条边的前一个点到n的距离小于后一个点到n的距离的一条路径。

    首先求出每一个点到n的最短路(spfa或者dijkstra),然后递推的求出1到n的受限路径数。

    f [ i ] 定义为 i 到n的受限路径数,将{dist[i],i}按距离排序,那么每次算f [ i ] 的时候需要保证dis [ i ] < dis [ j ] (j<i),而小于i的点的受限路径数量已经被算出来了。

    即f [ i ] 需要用到的值已经被算出来了,即递推关系是一个拓扑图,所以递推方案是可行的。

     1 typedef pair<int,int> PII;
     2 class Solution {
     3 public:
     4     const int mod=1e9+7;
     5     const int INF=0x3f3f3f3f;
     6     vector<vector<PII>> g;
     7     vector<int> dis;
     8     vector<bool> st;
     9     vector<int> f;
    10     void spfa(int n,vector<vector<int>>& edges){
    11         g.resize(n+1),dis.resize(n+1,INF),st.resize(n+1);
    12         for(auto edge:edges){
    13             int a=edge[0],b=edge[1],c=edge[2];
    14             g[a].push_back({b,c});
    15             g[b].push_back({a,c});
    16         }
    17         queue<int> q;
    18         dis[n]=0;
    19         q.push(n);
    20         while(q.size()){
    21             int t=q.front();
    22             q.pop();
    23             st[t]=false;
    24             for(auto x:g[t]){
    25                 int j=x.first,w=x.second;
    26                 if(dis[j]>dis[t]+w){
    27                     dis[j]=dis[t]+w;
    28                     if(!st[j]){
    29                         q.push(j);
    30                         st[j]=true;
    31                     }
    32                 }
    33             }
    34         }
    35     }
    36 
    37     int get_res(int n){
    38         f.resize(n+1);
    39         vector<PII> v;
    40         for(int i=1;i<=n;i++) v.push_back({dis[i],i});
    41         sort(v.begin(),v.end());
    42         f[n]=1;
    43         for(auto x:v){
    44             int d=x.first,u=x.second;
    45             for(auto p:g[u]){
    46                 int j=p.first;
    47                 if(d>dis[j]){
    48                     f[u]=(f[u]+f[j])%mod;
    49                 }
    50             }
    51         }
    52         return f[1];
    53     }
    54 
    55     int countRestrictedPaths(int n, vector<vector<int>>& edges) {
    56         spfa(n,edges);
    57         return get_res(n);
    58     }
    59 };

    D:给定一个数组和一个k,问保证每个长度为k的区间异或和为0需要改变的数的最小数目。

     1 class Solution {
     2 public:
     3     const int M=1024,INF=1e8;
     4     int s[1024];
     5     int minChanges(vector<int>& nums, int k) {
     6         int n=nums.size(),m=(n+k-1)/k;
     7         vector<vector<int>> f(k+1,vector<int>(M,INF));
     8         f[0][0]=0;
     9         int sum=0,minv=INF;
    10         for(int i=1;i<=k;i++){
    11             memset(s,0,sizeof s);
    12             int len=m;
    13             if(n%k && n%k<i) len--;
    14             for(int j=0;j<len;j++){
    15                 s[nums[j*k+i-1]]++;
    16             }
    17             int maxv=0;
    18             for(int j=0;j<M;j++){
    19                 if(s[j]) maxv=max(maxv,s[j]);
    20             }
    21             sum+=len-maxv,minv=min(minv,maxv);
    22             for(int j=0;j<M;j++){
    23                 for(int u=0;u<len;u++){
    24                     int x=nums[u*k+i-1],cost=len-s[x];
    25                     f[i][j]=min(f[i][j],f[i-1][j^x]+cost);
    26                 }
    27             }
    28         }
    29         return min(sum+minv,f[k][0]);
    30     }
    31 };
  • 相关阅读:
    2020年4月13日
    2021年4月12日
    梦断代码阅读笔记02
    Shell基本命令
    远程链接Linux
    Linux文档与目录结构
    VMware与Centos系统安装
    linux 第一天
    day88 Vue基础
    python 生成随机验证码
  • 原文地址:https://www.cnblogs.com/greenofyu/p/14497276.html
Copyright © 2020-2023  润新知