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 };
原文地址:https://www.cnblogs.com/greenofyu/p/14497276.html