初来乍到,周赛就出来两道题。目前的意思是将剩下两道题总结一下,方便以后再看
3
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;
}
};
我刚开始以为这个题目已经确定了圆形和半径,然后求点,主要是后来没时间了。。
现在理论分析一下,题目的意思就是给定一些点和圆的·半径,求一个可以包含最多点的圆包含的点的数目。难点是确定一个圆的圆心,知道圆心以后就可以直接求解某点到圆心的距离。代码也是参考的我能看懂的一份。