zoukankan      html  css  js  c++  java
  • Codeforces Round #409 (rated, Div. 2, based on VK Cup 2017 Round 2) 题解【ABCDE】

    A. Vicious Keyboard

    题意:给你一个字符串,里面只会包含VK,这两种字符,然后你可以改变一个字符,你要求VK这个字串出现的次数最多。

    题解:数据范围很小,暴力枚举改变哪个字符,然后check就好。

    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
        string s;
        cin>>s;
        int ans = 0;
        for(int i=0;i<s.size();i++){
            if(s[i]=='V'){
                s[i]='K';
            }else
                s[i]='V';
            int tmp = 0;
            for(int j=0;j<s.size()-1;j++){
                if(s[j]=='V'&&s[j+1]=='K')
                    tmp++;
            }
            ans=max(ans,tmp);
            if(s[i]=='V')
                s[i]='K';
            else
                s[i]='V';
        }
            int tmp = 0;
            for(int j=0;j<s.size()-1;j++){
                if(s[j]=='V'&&s[j+1]=='K')
                    tmp++;
            }
            ans=max(ans,tmp);
        cout<<ans<<endl;
    }
    

    B. Valued Keys

    题意:定义f(x,y),表示选择字符串中字典序最小的那个字符,然后现在你需要构造一个b,满足f(a,b)=c

    题解:如果c[i]>a[i],那么就显然非法,否则b[i]=c[i]即可。

    #include<bits/stdc++.h>
    using namespace std;
    
    int main(){
        string a,b,c;
        cin>>a>>b;
        for(int i=0;i<a.size();i++){
            if(b[i]>a[i]){
                cout<<"-1"<<endl;
                return 0;
            }else
                c+=b[i];
        }
        cout<<c<<endl;
    }
    

    C. Voltage Keepsake

    题意:你有个充电器,每秒钟可以充p的电。然后你有n个装置,每个装置每秒钟增加a[i],一开始有b[i]。请问最多多少秒,可以使得每一个装置都能运作下去。

    题解:显然的二分答案,呈现单调性。然后我们贪心的去充电即可。注意二分的姿势应该是枚举二分的次数。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e5+7;
    double a[maxn],b[maxn],p;
    int n;
    bool check(double x){
        double las=x*p;
        for(int i=0;i<n;i++){
            if(b[i]+las<a[i]*x)return false;
            if(b[i]>=a[i]*x)continue;
            las-=(a[i]*x-b[i]);
        }
        return true;
    }
    int main(){
        cin>>n>>p;
        for(int i=0;i<n;i++)
            cin>>a[i]>>b[i];
        //cout<<check(2)<<endl;
        double l = 0,r = 1e15;
        for(int i=0;i<150;i++){
            double mid = (l+r)/2.0;
            if(check(mid))l=mid;
            else r=mid;
            //cout<<l<<" "<<r<<endl;
        }
        if(l>=1e14){
            cout<<"-1"<<endl;
        }else{
            printf("%.10f
    ",l);
        }
    }
    

    D. Volatile Kite

    题意:问你凸包上每个点最多移动多少,可以使得这个凸包仍然是一个凸包。

    题解:答案就是p[i]这个点,离p[i-1],p[i+1]点的距离,最小值除以2。至于答案为什么这个,我就猜了一发结论,然后交一发就过了。。。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e3+6;
    struct node{
        double x,y;
    }p[maxn];
    int n;
    double dis(node A,node B){
        return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
    }
    double area(node A,node B,node C){
        double l1 = dis(A,B);
        double l2 = dis(B,C);
        double l3 = dis(A,C);
        double p = (l1+l2+l3)/2.0;
        return sqrt(p*(p-l1)*(p-l2)*(p-l3));
    }
    int main(){
        scanf("%d",&n);
        for(int i=0;i<n;i++){
            cin>>p[i].x>>p[i].y;
        }
        double ans = 1e15;
        for(int i=0;i<n;i++){
            ans = min(ans,area(p[i],p[(i+1)%n],p[(i-1+n)%n])*2/dis(p[(i+1)%n],p[(i-1+n)%n]));
        }
        printf("%.12f
    ",ans/2.0);
        //cout<<ans/2<<endl;
    }
    

    C. Vulnerable Kerbals

    题意:你需要构造一个最长的序列,满足以下要求:

    1.前缀乘积在%m的情况下,应该都不一样。

    2.规定的n个数,不能在前缀乘积中出现。

    3.序列中的每个数都应该是[0,m)的。

    题解:假设gcd(a,m)%gcd(b,m)==0,那么就显然会存在一个k,使得ak%m=b。那么这道题就按照gcd分类,然后用dp求一个最长路,然后再解同余方程,求解每一个k即可。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 2e5+7;
    vector<int> P[maxn],E[maxn];
    int n,m,vis[maxn],dp[maxn],from[maxn],phi[maxn];
    int gcd(int a,int b){
        if(b==0)return a;
        return gcd(b,a%b);
    }
    long long qpow(long long a,long long b,long long c){
        long long res = 1;
        while(b){
            if(b&1)res=res*a%c;
            a=a*a%c;
            b>>=1;
        }
        return res;
    }
    void pre(){
        for(int i=1;i<maxn;i++){
            phi[i]+=i-1;
            for(int j=2*i;j<maxn;j+=i){
                phi[j]-=phi[i];
            }
        }
    }
    int main(){
        pre();
        scanf("%d%d",&n,&m);
        if(m==1){
            cout<<"1
    0
    "<<endl;
            return 0;
        }
        for(int i=1;i<=n;i++){
            int x;scanf("%d",&x);
            vis[x]=1;
        }
        for(int i=0;i<m;i++){
            if(vis[i])continue;
            P[gcd(i,m)].push_back(i);
        }
        int mx = 0;
        for(int i=m;i>0;i--){
            from[i]=-1;
            for(int j=2*i;j<m;j+=i){
                if(dp[j]>dp[i]){
                    dp[i]=dp[j];
                    from[i]=j;
                }
            }
            dp[i]+=P[i].size();
            if(dp[i]>dp[mx]){
                mx=i;
            }
        }
        if(vis[0]==0)dp[mx]++;
        cout<<dp[mx]<<endl;
        int last = 1;
        while(mx!=-1){
            for(int i=0;i<P[mx].size();i++){
                int x = P[mx][i];
                int g = gcd(last,x);
                g = gcd(g,m);
                cout<<(x/g)*qpow((last/g),phi[m/g]-1,m/g)%(m/g)<<" ";
                last=x;
            }
            mx=from[mx];
        }
        if(vis[0]==0)cout<<"0";
        cout<<endl;
    }
  • 相关阅读:
    前端知识体系
    前端知识大总结(全)
    控制div层的显示以及隐藏
    让一个比较宽的banner位于页面中间
    数据结构之树(二)
    数据结构之树(一)
    数据结构之队列
    数据结构之栈
    数据结构之线性表(二)
    数据结构之线性表(一)
  • 原文地址:https://www.cnblogs.com/qscqesze/p/6728022.html
Copyright © 2011-2022 走看看