【题解】超级码力复赛题解 (3缺1,1题待补)
超级码力复赛题解 3缺1
是可行解,但大概不是最优解。
1,密钥
时间复杂度允许,就枚举两种字符,然后直接贪心。
class Solution {
public:
int a[1000100],n;
int solve(int v1,int v2)
{
int res=-1;int num1=0,num2=0;
for(int i=1;i<=n;i++)
{
if(a[i]==v1)num1++;
else if(a[i]==v2)num2++;
if(num1>=num2&&num2)res=max(num1-num2,res);
else if(num1<num2)num1=num2=0;
}
return res;
}
int key(string &s) {
n=s.length();
int res=0;
for(int i=0;i<n;i++)a[i+1]=s[i]-'0';
for(int i=0;i<=9;i++)
for(int j=0;j<=9;j++)
if(i!=j)res=max(res,solve(i,j));
return res;
}
};
2,吃鸡
这个是斯坦纳树的模板题。
#define mkp(a,b) make_pair(a,b)
typedef long long ll;
const int maxn=1e5+5;
const int inf=0x3f3f3f3f;
int head[maxn],to[maxn<<2],nxt[maxn<<2],ww[maxn<<2],pcnt;
inline void add(int u,int v,int w){
to[++pcnt]=v;nxt[pcnt]=head[u];ww[pcnt]=w;head[u]=pcnt;
}
int a[300];
ll dp[maxn][300];
priority_queue<pair<ll,int>>que;
void Dij(int sta)
{
pair<int,int>pr;
while(!que.empty())
{
pr=que.top();que.pop();
for(int i=head[pr.second];i;i=nxt[i]){
if(dp[to[i]][sta]>dp[pr.second][sta]+ww[i]){
dp[to[i]][sta]=dp[pr.second][sta]+ww[i];
que.push(mkp(-dp[to[i]][sta],to[i]));
}
}
}
}
class Solution {
public:
/**
* @param n: n islands
* @param k: k special islands
* @param m: The number of the two islands and the time spent crossing the bridge connecting the two islands
* @return: Time spent on the bridge through all the small islands
*/
long long cost(int n, vector<int> &k, vector<vector<int>> &m) {
int kk=k.size();
for(auto v:m){
add(v[0],v[1],v[2]);add(v[1],v[0],v[2]);
}
memset(dp,inf,sizeof(dp));ll INF=dp[0][0];
for(int i=0;i<kk;i++)a[i]=k[i];
for(int i=0;i<kk;i++)dp[a[i]][1<<i]=0;
for(int sta=1,up=1<<kk;sta<up;sta++){
for(int i=1;i<=n;i++)
{
for(int s=sta&(sta-1);s;s=sta&(s-1))
dp[i][sta]=min(dp[i][sta],dp[i][sta^s]+dp[i][s]);
if(dp[i][sta]!=INF)que.push(mkp(-dp[i][sta],i));
}
Dij(sta);
}
return dp[a[0]][(1<<kk)-1];
}
};
3,权限
还不会做,题意也看不太明白qwq,待补 等题解。
4,健美
感觉自己的做法不是正解。
整除分块+剪枝+数组&&map记录
typedef long long ll;
const int maxn=1e6+5;
ll f[maxn];
class Solution {
public:
/**
* @param n: n players
* @param p: Show time p
* @param v: Evaluation time v
* @return: How soon will the evaluation be completed
*/
ll p,v;
map<ll,ll>mp;
ll cal(ll x)
{
if(x<maxn&&f[x])return f[x];
else if(x>=maxn&&mp.count(x))return mp[x];
if(x==1)return 0;
if(x*p<=v)return f[x]=x*p+v;
if(x<=5)return f[x]=x*p+v;
ll res=x*p+v,l,r,t;
l=max((ll)sqrt(x),1ll);
if(x>=1e10)l=x/4;
else if(x>=1e8)l=x/8;
else if(x>=1e6)l=x/16;
else if(x>=1e4)l=x/32;
for(;l<x;l=r+1){
r=(x-1)/((x-1)/l);
if((x-1)/l+1>l)continue;
t=((x-1)/l+1)*p+v;
if(t>=res)break;
res=min(res,t+cal(l));
}
if(x<maxn)f[x]=res;
else mp[x]=res;
return res;
}
long long shortestTime(long long n, int p, int v) {
memset(f,0,sizeof(f));mp.clear();
this->p=p;this->v=v;
return cal(n);
}
};