输入
["FoodRatings", "highestRated", "highestRated", "changeRating", "highestRated", "changeRating", "highestRated"]
[[["kimchi", "miso", "sushi", "moussaka", "ramen", "bulgogi"], ["korean", "japanese", "japanese", "greek", "japanese", "korean"], [9, 12, 8, 15, 14, 7]], ["korean"], ["japanese"], ["sushi", 16], ["japanese"], ["ramen", 16], ["japanese"]]
输出
[null, "kimchi", "ramen", null, "sushi", null, "ramen"]解释
FoodRatings foodRatings = new FoodRatings(["kimchi", "miso", "sushi", "moussaka", "ramen", "bulgogi"], ["korean", "japanese", "japanese", "greek", "japanese", "korean"], [9, 12, 8, 15, 14, 7]);
foodRatings.highestRated("korean"); // 返回 "kimchi"
// "kimchi" 是分数最高的韩式料理,评分为 9 。
foodRatings.highestRated("japanese"); // 返回 "ramen"
// "ramen" 是分数最高的日式料理,评分为 14 。
foodRatings.changeRating("sushi", 16); // "sushi" 现在评分变更为 16 。
foodRatings.highestRated("japanese"); // 返回 "sushi"
// "sushi" 是分数最高的日式料理,评分为 16 。
foodRatings.changeRating("ramen", 16); // "ramen" 现在评分变更为 16 。
foodRatings.highestRated("japanese"); // 返回 "ramen"
// "sushi" 和 "ramen" 的评分都是 16 。
// 但是,"ramen" 的字典序比 "sushi" 更小。
因为要返回某一类烹饪方式下评分最高的食物,就先想到用哈希表建立烹饪方式到评分和食物的映射,又评分要有序,所以想到用set,又因为要支持修改操作,修改一个食物的评分要修改要把set中的原评分删除,然后添加新的评分,删除操作已知的是食物,所以要建立食物到评分的映射,和食物到烹饪方式的映射。
class FoodRatings {
public:
//struct Data {
// int rating;
// string food;
// bool operator< (const Data& t) const {
// if (rating != t.rating) return rating > t.rating;
// return food < t.food;
// }
//};
//unordered_map> hash;
unordered_map>> hash;//烹饪方式->(评分 食物)
unordered_map cui;//食物->烹饪方式
unordered_map rat;//食物->评分
FoodRatings(vector& foods, vector& cuisines, vector& ratings) {
for(int i=0;isecond;
//return hash[cuisine].begin()->food;
}//若使用结构体,评分就不用存负数
};
/**
* Your FoodRatings object will be instantiated and called as such:
* FoodRatings* obj = new FoodRatings(foods, cuisines, ratings);
* obj->changeRating(food,newRating);
* string param_2 = obj->highestRated(cuisine);
*/
输入:nums = [1,2,3,1], k = 3
输出:5
解释:有如下几个优质数对:
- (3, 3):(3 AND 3) 和 (3 OR 3) 的二进制表示都等于 (11) 。值为 1 的位数和等于 2 + 2 = 4 ,大于等于 k = 3 。
- (2, 3) 和 (3, 2): (2 AND 3) 的二进制表示等于 (10) ,(2 OR 3) 的二进制表示等于 (11) 。值为 1 的位数和等于 1 + 2 = 3 。
- (1, 3) 和 (3, 1): (1 AND 3) 的二进制表示等于 (01) ,(1 OR 3) 的二进制表示等于 (11) 。值为 1 的位数和等于 1 + 2 = 3 。
所以优质数对的数目是 5 。
如果 num1
在数组中至少出现 一次 ,则满足 num1 == num2
的数对 (num1, num2)
也可以是优质数对。也就是说一个数只要出现了,那出现多少次都没区别,所以可以先去重。
至于两数与运算和或运算后1的个数之和
举例 或运算 与运算
10100 11101 00100
01101
发现
若两数该位为11 则计算后总的1的个数加2
若两数该位为10或01 则计算后总的1的个数加1
若两数该位为00 则计算后总的1的个数加0
所以两数做与运算后1的个数+做或运算后1的个数之和等于做运算前两数1的个数之和
所以就把问题转化为两数1的个数之和大于等于k的数对的个数
class Solution {
public:
long long countExcellentPairs(vector& nums, int k) {
typedef long long LL;
sort(nums.begin(),nums.end());
nums.erase(unique(nums.begin(),nums.end()),nums.end());
int cnt[30]={0};//2^30略大于10^9 所以最多有30个1
for(auto x:nums){
int s=0;
while(x) x&=(x-1),s++;//计算1的个数
cnt[s]++;//记录 1的个数为s的数有多少个
}
LL res=0;
for(int i=0;i<30;i++)//枚举i
for(int j=max(k-i,0);j<30;j++)//再找满足大于等于k条件的能够与i配对的j
res+=(LL)cnt[i]*cnt[j];//满足条件1的个数为i和j的数的个数相乘即为所有配对方案
return res;
}
};
3
10
20
30
因为一个角度顺时针拨动,要么逆时针拨动,且数据范围在25以内,所以可以用二进制枚举。
#include
#include
#include
using namespace std;
const int N=20;
int a[N];
int main()
{
int n;
cin >> n;
int sum=0;
for(int i=0;i> a[i];
sum+=a[i];
}
bool flag=false;
for(int i=0;i<1<>j)&1){
tmp+=a[j];
}
}
if(((sum-2*tmp)%360+360)%360==0){//若顺时针和逆时针拨动的角度模360不为0 则无法复原
puts("YES");
flag=true;
break;
}
}
if(!flag) puts("NO");
return 0;
}
共一行,包含 5 个整数 R,x1,y1,x2,y2。
5 3 3 1 1
3.767767 3.767767 3.914214
把图画出来后就不难发现,若要满足题目的条件,画的圆的圆心一定在给定点和给定圆圆心连线的延长线上,直径为给定点到延长线与给定圆交点的长度,又因为知道给定圆的半径,所以给定圆圆心到画圆圆心的距离等于给定圆半径减去画圆半径,又三点一线,可以用向量求画圆圆心的位置,这样误差也比平方的求法小。(说了这么多废话,画个图就明白了)
#include
#include
#include
#include
using namespace std;
int main()
{
double R,x1,y1,x2,y2;
cin >> R>>x1>>y1>>x2>>y2;
double z=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
if(x1==x2&&y1==y2){
printf("%.6lf %.6lf %.6lf",x1+R/2,y1,R/2);
return 0;
}
if(z>=R){
printf("%.6lf %.6lf %.6lf",x1,y1,R);
}
else{
double ra=(z+R)/2;//画圆的半径
double d=R-ra;//画圆圆心到给定圆圆心的距离
//因为三点在一条直线上且已知两点和线段的比例关系 使用向量
double tx=x1-x2,ty=y1-y2;//向量(x1->x2,y1->y2)与向量(x->x1,y->y1)的比值是z:d
//则向量(x->x1,y->y1)为(tx/z*d,ty/z*d) 则x,y分别(x1+tx/z*d,y1+ty/z*d)
x1+=tx/z*d,y1+=ty/z*d;
printf("%.6lf %.6lf %.6lf", x1, y1, ra);
}
}