1.转化时间需要的最少操作数
考点:贪心/BFS
贪心代码:
class Solution {
public:
int convertTime(string current, string correct) {
int a,b,c,d;
sscanf(current.c_str(),"%d:%d",&a,&b);
sscanf(correct.c_str(),"%d:%d",&c,&d);
int t1=a*60+b;
int t2=c*60+d;
//贪心
int ans=0;
while(t1!=t2){
//每次看+1,+5,+15,+60哪个可以最大化离t2最近
//显然如果t1加上大的数没超过t2,那我们肯定每次操作加大的数更好,这样可以让我快速接近t2
//从而达到贪心的目的,使得操作次数最少
if(t1+60<=t2)t1+=60;
else if(t1+15<=t2)t1+=15;
else if(t1+5<=t2)t1+=5;
else if(t1+1<=t2)t1+=1;
ans++;
}
return ans;
}
};
BFS代码:
class Solution {
int dis[2010];
public:
int convertTime(string current, string correct) {
int a,b,c,d;
sscanf(current.c_str(),"%d:%d",&a,&b);
sscanf(correct.c_str(),"%d:%d",&c,&d);
int t1=a*60+b;
int t2=c*60+d;
//广搜
memset(dis,-1,sizeof dis);
dis[t1]=0;
queue<int>q;
q.push(t1);
while(q.size()){
int t=q.front();
q.pop();
if(t+1<=2000&&dis[t+1]==-1)dis[t+1]=dis[t]+1,q.push(t+1);
if(t+5<=2000&&dis[t+5]==-1)dis[t+5]=dis[t]+1,q.push(t+5);
if(t+15<=2000&&dis[t+15]==-1)dis[t+15]=dis[t]+1,q.push(t+15);
if(t+60<=2000&&dis[t+60]==-1)dis[t+60]=dis[t]+1,q.push(t+60);
}
return dis[t2];
}
};
2.找出输掉零场或一场比赛的玩家
https://leetcode-cn.com/contest/weekly-contest-287/problems/find-players-with-zero-or-one-losses/
考点:模拟
class Solution {
int ma[100010];
set<int>hs;
public:
vector<vector<int>> findWinners(vector<vector<int>>& matches) {
int len=matches.size();
for(int i=0;i<len;i++)
{
vector<int>t=matches[i];
int a=matches[i][0],b=matches[i][1];
//b是loser
ma[b]++;
hs.insert(a),hs.insert(b);
}
vector<vector<int>>ans(2);
for(auto x:hs){
if(!ma[x])ans[0].push_back(x);
if(ma[x]==1)ans[1].push_back(x);
}
sort(ans[0].begin(),ans[0].end());
sort(ans[1].begin(),ans[1].end());
return ans;
}
};
3.每个小孩最多能分到多少糖果
https://leetcode-cn.com/contest/weekly-contest-287/problems/maximum-candies-allocated-to-k-children/
考点:二分答案
class Solution {
public:
bool check(long long x,vector<int>ans,long long k)
{
long long cnt=0;
for(int i=0;i<ans.size();i++){
cnt+=ans[i]/x; //这一堆最多能分成多少个糖果个数是x的堆
}
return cnt>=k;
}
int maximumCandies(vector<int>& a, long long k) {
long long l=0,r=1e12;
while(l<r)
{
long long mid=(l+r+1)/2;
if(check(mid,a,k))l=mid;
else r=mid-1;
}
return l;
}
};
4 加密解密字符串
https://leetcode-cn.com/contest/weekly-contest-287/problems/encrypt-and-decrypt-strings/
考点:哈希表,逆向思维
class Encrypter {
unordered_map<char,int>mc; //用于字符对映下标
vector<string>ve;
vector<string>sb;
public:
Encrypter(vector<char>& keys, vector<string>& values, vector<string>& dictionary) {
//映射一下
for(int i=0;i<keys.size();i++){
mc[keys[i]]=i;
}
ve=values;
sb=dictionary;
}
string encrypt(string word1) {
string ans;
for(auto x:word1){
ans+=ve[mc[x]];
}
return ans;
}
int decrypt(string word2) {
//解密(由于word2解密得到的字符串有可能是多个的,但题目只要求我们找到解密之后在字典里面的字符串个数)
/*
首先一个字符串加密的结果是唯一的,因为keys里面的字符是互不相同
由于word2解密是一对多,
这说明我们在字典里面有多个字符串加密之后得到的字符串是相同的,
所以我们可以反过来想,对字典里面的字符串进行加密,统计有几个字符串加密等于word2即可
*/
int res=0;
for(auto s:sb){
if(encrypt(s)==word2)res++;
}
return res;
}
};
/**
* Your Encrypter object will be instantiated and called as such:
* Encrypter* obj = new Encrypter(keys, values, dictionary);
* string param_1 = obj->encrypt(word1);
* int param_2 = obj->decrypt(word2);
*/
强啊!