Leetcode-周竞赛

初来乍到,周赛就出来两道题。目前的意思是将剩下两道题总结一下,方便以后再看

5414 收藏清单

给你一个数组 favoriteCompanies ,其中 favoriteCompanies[i] 是第 i 名用户收藏的公司清单(下标从 0 开始)。

请找出不是其他任何人收藏的公司清单的子集的收藏清单,并返回该清单下标。下标需要按升序排列。

 

示例 1:

输入:favoriteCompanies = [["leetcode","google","facebook"],["google","microsoft"],["google","facebook"],["google"],["amazon"]]
输出:[0,1,4] 
解释:
favoriteCompanies[2]=["google","facebook"] 是 favoriteCompanies[0]=["leetcode","google","facebook"] 的子集。
favoriteCompanies[3]=["google"] 是 favoriteCompanies[0]=["leetcode","google","facebook"] 和 favoriteCompanies[1]=["google","microsoft"] 的子集。
其余的收藏清单均不是其他任何人收藏的公司清单的子集,因此,答案为 [0,1,4] 。
示例 2:

输入:favoriteCompanies = [["leetcode","google","facebook"],["leetcode","amazon"],["facebook","google"]]
输出:[0,1] 
解释:favoriteCompanies[2]=["facebook","google"] 是 favoriteCompanies[0]=["leetcode","google","facebook"] 的子集,因此,答案为 [0,1] 。
示例 3:

输入:favoriteCompanies = [["leetcode"],["google"],["facebook"],["amazon"]]
输出:[0,1,2,3]
 

提示:

1 <= favoriteCompanies.length <= 100
1 <= favoriteCompanies[i].length <= 500
1 <= favoriteCompanies[i][j].length <= 20
favoriteCompanies[i] 中的所有字符串 各不相同 。
用户收藏的公司清单也 各不相同 ,也就是说,即便我们按字母顺序排序每个清单, favoriteCompanies[i] != favoriteCompanies[j] 仍然成立。
所有字符串仅包含小写英文字母。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/people-whose-list-of-favorite-companies-is-not-a-subset-of-another-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

vector<int> peopleIndexes(vector<vector<string>>& fa) {
        int n=fa.size();
        vector<int> res;
        for(auto &f: fa) sort(f.begin(), f.end());//这里是将一维里面的进行排序
        for(auto &f: fa) {
            for(auto &t: f) {
                cout<<t<<" ";
            }
            cout<<endl;
        }

        for(int i=0; i<n; ++i){
            bool flag=true;
            for(int j=0; j<n; ++j){
                if(i!=j && fa[i].size()<=fa[j].size()){
                    int cur=0;
                    for(int k=0; k<fa[j].size(); ++k){
                        if(cur<fa[i].size() && fa[i][cur]==fa[j][k]) ++cur;
                        //如果两个列表里面单词一样的话,cur++;
                    }
                    if(cur==fa[i].size()) flag=false;
                }
            }
            if(flag) res.push_back(i);
        }
        //三个for,空间有些大
        return res;
    }

//我最初的一个想法就是如果列表中包含只出现过一次的单词,说明该列表需要记录,可是,明显不符合后面例子的情况,所以就参考我能看懂的·1大佬的写法,就是先将列表里面的单词排序,然后将一个列表于其他列表里面的单词进行比较,相同就cur加1,如果最后cur等于该列表的长度,那么说明该列表是某一个列表的子集,就不放入res,否则的话,就将该列表放入res。

如果一个列表的长度,大于其他列表长度,说明该列表内容肯定和其他列表的不同,就直接将自己位置加入res。

4

5415 圆形靶内的最大飞镖数量

墙壁上挂着一个圆形的飞镖靶。现在请你蒙着眼睛向靶上投掷飞镖。

投掷到墙上的飞镖用二维平面上的点坐标数组表示。飞镖靶的半径为 r 。

请返回能够落在 任意 半径为 r 的圆形靶内或靶上的最大飞镖数。

 

示例 1:

输入:points = [[-2,0],[2,0],[0,2],[0,-2]], r = 2
输出:4
解释:如果圆形的飞镖靶的圆心为 (0,0) ,半径为 2 ,所有的飞镖都落在靶上,此时落在靶上的飞镖数最大,值为 4 。
示例 2:

输入:points = [[-3,0],[3,0],[2,6],[5,4],[0,9],[7,8]], r = 5
输出:5
解释:如果圆形的飞镖靶的圆心为 (0,4) ,半径为 5 ,则除了 (7,8) 之外的飞镖都落在靶上,此时落在靶上的飞镖数最大,值为 5 。
示例 3:

输入:points = [[-2,0],[2,0],[0,2],[0,-2]], r = 1
输出:1
示例 4:

输入:points = [[1,2],[3,5],[1,-1],[2,3],[4,1],[1,3]], r = 2
输出:4
 

提示:

1 <= points.length <= 100
points[i].length == 2
-10^4 <= points[i][0], points[i][1] <= 10^4
1 <= r <= 5000


来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-number-of-darts-inside-of-a-circular-dartboard
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

struct point{
    double x,y;
    point(double i,double j):x(i),y(j){}
};

//算两点距离
double dist(double x1,double y1,double x2,double y2){
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

//计算圆心
point f(point& a,point& b,int r){
    //算中点
    point mid((a.x+b.x)/2.0,(a.y+b.y)/2.0);
    //cout<<"mid"<< " "<<mid.x<<" "<<mid.y<<endl;
    //AB距离的一半
    double d=dist(a.x,a.y,mid.x,mid.y);
    //cout<<"d"<< " "<<d<<endl;
    //计算h
    double h=sqrt(r*r-d*d);
    //cout<<"h"<< " "<<h<<endl;
    //计算垂线
    point ba(b.x-a.x,b.y-a.y);
    //cout<<"ba"<< " "<<ba.x<<" "<<ba.y<<endl;
    point hd(-ba.y,ba.x);
   // cout<<"hd"<< " "<<hd.x<<" "<<hd.y<<endl;
    double len=sqrt(hd.x*hd.x+hd.y*hd.y);
    //cout<<"len"<< " "<<len<<endl;
    hd.x/=len,hd.y/=len;//我们需要的是其方向   
    //cout<<hd.x<<" "<<hd.y<<endl; 
    hd.x*=h,hd.y*=h;
    //cout<<hd.x<<" "<<hd.y<<endl;
    //cout<<"圆心"<< " "<<hd.x+mid.x<<" "<<hd.y+mid.y<<endl;
    return point(hd.x+mid.x,hd.y+mid.y);
    ///这块还需要输出理解一下
}

class Solution {
public:
    int numPoints(vector<vector<int>>& points, int r) {
        int n=points.size();
        int ans=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(i==j){//一个点
                    int cnt=0;
                    for(int k=0;k<n;k++){
                        double tmp=dist(points[i][0],points[i][1],points[k][0],points[k][1]);
                        if(tmp<=r) cnt++;
                    }
                    ans=max(cnt,ans);
                }else{//两个点
                    //通过长度判断有没有圆心
                    //就是已知两个点和半径,可以知道一个圆,这里就是通过两个点来确定的圆来判断其他点是不是也符合要求,如果符合,cnt+1.
                    //最终我们需要的是cnt最大。
                    double d=dist(points[i][0],points[i][1],points[j][0],points[j][1]);
                    if(d/2>r) continue;

                    point a(points[i][0],points[i][1]),b(points[j][0],points[j][1]);
                    point res=f(a,b,r);
                    int cnt=0;
                    for(int k=0;k<n;k++){
                        double tmp=dist(res.x,res.y,points[k][0],points[k][1]);
                        if(tmp<=r) cnt++;
                    }
                    ans=max(cnt,ans);
                }
            }
        }
        return ans;
    }
};

我刚开始以为这个题目已经确定了圆形和半径,然后求点,主要是后来没时间了。。

现在理论分析一下,题目的意思就是给定一些点和圆的·半径,求一个可以包含最多点的圆包含的点的数目。难点是确定一个圆的圆心,知道圆心以后就可以直接求解某点到圆心的距离。代码也是参考的我能看懂的一份。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值