Codeforces Round #409 解题报告

801A - Vicious Keyboard

只能说难受,被systest卡了。
题意:给一串由V ,K字母组成的字符串,任意改变一个字符(也可不改变)使得其中VK子串数量最大
Solution: 找VK数量,再找3连K,或3连V,或开头是KKV,或结尾VVK的,注意N==2要特判

//Author: Lixiang
#include
#include
const int maxl=101;
struct A{
    char s[maxl];
    int N,cnt;
    void init(){
        scanf("%s",s);
        N=strlen(s);
        for(int i=0;i1;i++)
            if(s[i]=='V'&&s[i+1]=='K')cnt++;
    }
    void work(){
        int flag=0;
        for(int i=0;i2;i++)
            if(s[i]==s[i+1]&&s[i+1]==s[i+2]){
                flag=1;
                break;
            }
        if(N==2){
            if(s[0]==s[1])flag=1;
        }
        else{
            if(s[0]=='K'&&s[1]=='K'&&s[2]=='V')flag=1;
            if(s[N-1]=='V'&&s[N-2]=='V'&&s[N-3]=='K')flag=1;
        }
        printf("%d\n",cnt+flag);
    }
}sol;
int main(){
    sol.init();
    sol.work();
    return 0;
}

801B - Valued Keys

水题

//Author: Lixiang
#include
#include
struct B{
    char a[101],b[101],c[101];
    int N;
    void init(){
        scanf("%s%s",a,c);
        N=strlen(a);
    }
    void work(){
        for(int i=0;iif(a[i]>=c[i])b[i]=c[i];
            else{
                puts("-1");
                return ;
            }
        }
        puts(b);
    }
}sol;
int main(){
    sol.init();
    sol.work();
    return 0;
}

800A - Voltage Keepsake

题意:每个设备每单位时间耗电Ai,初始存储电量为Bi,有一个充电器每单位时间可对某一个设备充电P,当某一设备电量为0时,所有工作结束,求设备工作的最长时间。
Solution: 二分+贪心
哎╮(╯▽╰)╭,这题怕超时开的R=1e5 eps=1e-5,但正解R要开到1e12,很气。

//Author: Lixiang
#include
#include
using namespace std;
const int maxn=100001;
struct Node{
    long double a,b;
};
struct C{
    Node d[maxn];
    long double P,L,mm;
    int N;
    long double ss;
    void init(){
        ios::sync_with_stdio(false);
        L=0;mm=0;
        cin>>N>>P;
        for(int i=1;i<=N;i++){
            cin>>d[i].a>>d[i].b;
            d[i].b*=100000;
        }
    }
    bool check(long double M){
        long double sum=0;
        for(int i=1;i<=N;i++){
            if(d[i].a*Mcontinue;
            sum+=(d[i].a*M-d[i].b)/P;
            if(sum>M)return 0;
        }
        return 1;
    }
    void work(){
        long double R=1e18,M;
        long double ans=-1;
        while((R-L)>1){
            M=(L+R)/2.0;
            if(check(M)){
                L=M;
                ans=M;
            }
            else R=M;
        }
        if(ans>1e16)puts("-1");
        else cout<100000.0;
    }
}sol;
int main(){
    sol.init();
    sol.work();
    return 0;
}

800B - Volatile Kite

求一遍凸包,再对每连续三个点求点到直线距离d,ans=min{d/2},具体见代码。

//Author: Lixiang
#include
#include
#include
using namespace std;
int n,top;
double ans;
struct data{
   double x,y;
}p[10001],s[10001];
double mul(data p1,data p2,data p0){
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
double dis(data a,data b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
inline bool cmp(data a,data b)
{
    if(mul(a,b,p[0])==0)return dis(a,p[0])0]);
    return mul(a,b,p[0])>0;
}
double dis2(data p1,data p2,data p3){
    double x1=p1.x,y1=p1.y,x2=p3.x,y2=p3.y,x=p2.x,y=p2.y;
    double A=y2-y1,B=x1-x2,C=x2*y1-x1*y2;
    return (A*x+B*y+C)/2.0/sqrt(A*A+B*B);
}
void graham(){
    top=2;data t;
    int k=0;
    for(int i=1;iif((p[k].y>p[i].y)||(p[k].y==p[i].y&&p[k].x>p[i].x))k=i;
    t=p[0];p[0]=p[k];p[k]=t;
    sort(p+1,p+n,cmp);
    s[0]=p[0],s[1]=p[1],s[2]=p[2];
    for(int i=3;iwhile(top&&mul(p[i],s[top],s[top-1])>=0)
           top--;
        s[++top]=p[i];
    }
    ans=min(dis2(s[top],s[0],s[1]),dis2(s[top-1],s[top],s[0]));
    for(int i=0;i1;i++)
        ans=min(ans,dis2(s[i],s[i+1],s[i+2]));
}
int main(){
    scanf("%d",&n);
    for(int i=0;iscanf("%lf%lf",&p[i].x,&p[i].y);
    graham();
    printf("%.10lf\n",ans);
    return 0;
}

800C - Vulnerable Kerbals

Solution:假设我们求出的前缀乘积的顺序是这样的 p1,p2,...,pk .产生的序列为 a1,a2,...,ak ,那么就一定有, pi1×aipi(mod m) 则一定会有 gcd(pi1,m)|pi ,(按照这个关系在 pi1 ,与 pi 之间建边就是一个DAG)因此我们可以将可以作为前缀乘积的数按照与m的gcd分类,相同gcd值作为顶点,不同gcd值满足整除关系就建一条边,最终形成一个DAG,跑一遍最长路就好了.
注意求解同于方程的时候可能会溢出,用long long。

#include
#include
#include
using namespace std;
const int maxn=200001;
inline long long gcd(long long a,long long b){
    if(b==0)return a;
    else return gcd(b,a%b);
}
inline long long exgcd(long long a,long long b,long long &x,long long &y){
    long long r=a;
    if(b==0)x=1,y=0;
    else{
        r=exgcd(b,a%b,x,y);
        long long t=x;
        x=y;
        y=t-a/b*y;
    }
    return r;
}
long long Equa(long long a,long long b,long long n){
    long long x,y,x0,i;
    long long d=exgcd(a,n,x,y);
    x0=x*(b/d)%n;
    while(x0<0)x0=(x0+n/d)%n;
    return x0;
}
struct E{
    vector <int> ADJL[maxn];
    stack <long long> seq;
    int cnt[maxn],f[maxn],fa[maxn],N,M;
    bool ban[maxn];
    void init(){
        scanf("%d%d",&N,&M);
        for(int i=1,t;i<=N;i++){
            scanf("%d",&t);
            ban[t]=1;
        }
        for(int i=0;iif(!ban[i]){
                cnt[gcd(i,M)]++;
                ADJL[gcd(i,M)].push_back(i);
            }
    }
    void work(){
        vector <int>::iterator it;
        int ans=0,st;
        long long last;
        for(int i=0;i<=M;i++){
            if(cnt[i]==0)continue;
            for(int j=0;jif(cnt[j]==0)continue;
                if(i%j!=0)continue;
                if(f[j]>f[i]){
                    f[i]=f[j];
                    fa[i]=j;
                }
            }
            f[i]+=cnt[i];
            if(f[i]>ans){
                ans=f[i];
                st=i;
            }
        }
        while(st!=0){
            for(it=ADJL[st].begin();it!=ADJL[st].end();it++)
                seq.push(*it);
            st=fa[st];
        }
        printf("%d\n",ans);
        if(ans==0)return;
        printf("%I64d",seq.top());
        last=seq.top();
        seq.pop();
        while(!seq.empty()){
            printf(" %I64d",Equa(last,seq.top(),M));
            last=seq.top();
            seq.pop();
        }
        puts("");
    }
}sol;
int main(){
    sol.init();
    sol.work();
    return 0;
}

你可能感兴趣的:(Codeforces)