leetcode 周赛 442

A:船上可以装载的最大集装箱数量

简单题,直接取min就可以了。

1 class Solution {
2 public:
3     int maxContainers(int n, int w, int maxWeight) {
4         return min(n*n, maxWeight/w);
5     }
6 };
View Code

B:属性图

考察并查集,因为数据规模较小,所以可以直接暴力枚举题目的建边条件。

更优雅的写法是可以调用C++的union和intersect操作。

 1 const int N = 100;
 2 int cnt[N][N];
 3 class Solution {
 4 public:
 5     int find(int x,vector<int>& p){
 6         if(p[x]!=x){
 7             p[x]=find(p[x],p);
 8         }
 9         return p[x];
10     }
11     int numberOfComponents(vector<vector<int>>& pro, int k) {
12         //并查集
13         int n=pro.size();
14         int m=pro[0].size();
15         vector<int> p(n,0);
16         for(int i=0;i<n;i++)
17             p[i]=i;
18         memset(cnt,0,sizeof cnt);
19         vector<set<int>> SS(n);
20         for(int i=0;i<n;i++){
21             for(int j=0;j<m;j++){
22                 SS[i].insert(pro[i][j]);
23             }
24         }
25         for(int i=0;i<n;i++){
26             for(int j=i+1;j<n;j++){
27                 for(auto x:SS[i]){
28                     if(SS[j].count(x)){
29                         cnt[i][j]++;
30                         cnt[j][i]++;
31                     }
32                 }
33             }
34         }
35         for(int i=0;i<n;i++){
36             for(int j=i+1;j<n;j++){
37                 if(cnt[i][j]>=k){
38                     p[find(i,p)]=p[find(j,p)];
39                 }
40             }
41         }
42         int res=0;
43         for(int i=0;i<n;i++){
44             if(p[i]==i)
45             {
46                 res++;
47             }
48         }
49         return res;
50     }
51 };
View Code

C:酿造药水需要的最少总时间

阅读理解题,最重要的条件是每个药水必须不间断的依次被各个巫师处理。

比如例1,第二瓶药不能直接开始,需要等很久,以此保证后面巫师没有还在处理第一瓶药。

 1 class Solution {
 2 public:
 3     long long minTime(vector<int>& skill, vector<int>& mana) {
 4         int n=skill.size();
 5         int m=mana.size();
 6         vector<long long> time(n);
 7         for(int i=0;i<m;i++){
 8             //顺推第这瓶药的完成时间(可以等),目标是得到这瓶药的完成时间。
 9             for(int j=0;j<n;j++){
10                 if(j==0)
11                     time[j]=time[j]+mana[i]*skill[j];
12                 else
13                     time[j]=max(time[j],time[j-1])+mana[i]*skill[j];
14             }
15             //逆推回去,补全第i瓶药在各个巫师受伤完成的时间,因为后面还需要用到这个完成时间。
16             for(int j=n-2;j>=0;j--){
17                 time[j]=time[j+1]-mana[i]*skill[j+1];
18             }
19             // for(int k=0;k<n;k++)
20             //     cout<<time[k]<<" ";
21             // cout<<endl;
22         }
23         return time.back();
24     }
25 };
View Code

D:使数组元素都变为零的最少操作次数

给定多个L~R,问需要多少次操作能将一个L~R都变为0,答案为所有query和。

对于一个query,显然ans=f(r)-f(l-1),而f(n),可以直接在log(n)的时间复杂度内计算出来。

 1 class Solution {
 2 public:
 3     long long f(int x){
 4         if(x<=0) return 0;
 5         long long res=0;
 6         vector<long long> tmp;
 7         long long m=1;
 8         while(m<=x){
 9             tmp.push_back(m);
10             m*=4;
11         }
12         for(int i=1;i<tmp.size();i++){
13             res+=(tmp[i]-tmp[i-1])*i;
14         }
15         res+=(x-tmp.back()+1)*tmp.size();
16         return res;
17     }
18     long long minOperations(vector<vector<int>>& queries) {
19         long long res=0;
20         for(int i=0;i<queries.size();i++){
21             int l=queries[i][0],r=queries[i][1];
22             res+=(f(r)-f(l-1)+1)/2;
23         }
24         return res;
25     }
26 };
View Code

 

posted on 2025-03-23 23:41  greenofyu  阅读(10)  评论(0)    收藏  举报