【题解】超级码力复赛题解 (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);
    }
};
posted @ 2020-09-18 18:40  草丛怪  阅读(137)  评论(0编辑  收藏  举报