Codeforces Round #339(Div.2)

嘛,为毛现在比赛都这么晚…
所以我就去看俺妹了…结果看到三点…比打比赛还晚诶…
嘛…虽然看过动画但再看小说依旧虐的不行…看到黑猫本子上的”和先辈分手”,整个人就不好了,于是睡到了11:30…

好吧,下面是题解:

A

题目大意:
求在[l,r]内k的幂的个数
题解:
这是个cha的好题,数据范围给了好大…
rank前几的都是几十Hack
代码:

#include <bits/stdc++.h>
using namespace std;

long long l,r,k,pow=1;
int cnt=0;
long long ans[100];

int main(){
    cin>>l>>r>>k;
    while(pow<=r){
        if(pow>=l) ans[cnt++]=pow;
        if((double)pow*k<=r) pow*=k; else break;
    }
    if(!cnt) puts("-1");
    else for(int i=0;i<cnt;i++) cout<<ans[i]<<' ';
    return 0;
}

B

题目大意:
给你一些形如10…0的数,和最多一个的其他数,求他们的乘积(product)
题解:
记录下特殊的数和0的个数
代码:

#include <bits/stdc++.h>
using namespace std;

string s,ss="1";
int n,zero=0;
bool flag=0;

int main(){
    cin>>n;
    while(n--){
        cin>>s;
        if(s.length()==1 && s[0]=='0'){
            puts("0");
            return 0;
        }
        bool ok=s[0]=='1';
        for(int i=1;i<s.length();i++)
            if(s[i]!='0'){
                ok=0;
                break;
            }
        if(ok) zero+=s.length()-1; else ss=s;
    }
    cout<<ss;
    while(zero--) cout<<0;
    return 0;
}

C

题目大意:
给出一个点P和一个多边形,求以P为圆心的圆环在包含整个多边形时的最小面积
题解:
我们只需求出每个点到P的距离d,答案就是PI*(maxd^2-mind^2),然后你就错了…
因为有些时候圆会在内部先与边切上再与点相交
怎么办呢?
由于点是顺时针给出的,只需依次计算p到线段的距离更新mind,p到端点的距离更新maxd
注意数据范围…
代码:

#include <bits/stdc++.h>
using namespace std;

const int MAXN=int(1e5+5);
const double PI=acos(-1);
int n;
struct Point{
    int x,y; double d;
    Point(){}
    Point(int x,int y);
}p,a[MAXN];
double Sqr(double x){return x*x;}
double Dis(Point A,Point B){return Sqrt(Sqr(A.x-B.x)+Sqr(A.y-B.y));}
long long Det(Point A,Point B,Point C){return 1ll*A.x*B.y+1ll*B.x*C.y+1ll*C.x*A.y-1ll*A.y*B.x-1ll*B.y*C.x-1ll*C.y*A.x;}
Point::Point(int x,int y):x(x),y(y){d=Dis(*this,p);}

int main(){
    cin>>n;
    cin>>p.x>>p.y;
    int x,y;
    for(int i=0;i<n;i++){
        cin>>x>>y;
        a[i]=Point(x,y);
    }
    double l,_min=1e18,_max=0;
    for(int i=0;i<n;i++){
        _min=min(_min,a[i].d);
        _max=max(_max,a[i].d);
        l=Dis(a[i],a[(i+1)%n]);
        if(Sqr(l)+Sqr(a[i].d)>Sqr(a[(i+1)%n].d) && Sqr(l)+Sqr(a[(i+1)%n].d)>Sqr(a[i].d)){
            _min=min(_min,abs((double)Det(a[i],p,a[(i+1)%n]))/l);
        }
    }
    printf("%.9f\n",PI*(Sqr(_max)-Sqr(_min)));
    return 0;
}

D

题目大意:
给你一个数列(元素大小上限为A),一个数m,参数cf和cm,将不超过m加到数列上,使得force=达到上限的元素的个数*cf+最小的元素值*cm最大
题解:
先将数列排序
从大到小依次将数据变为A,然后每次对最小值进行二分,计算出force进行更新
代码:

#include <bits/stdc++.h>
using namespace std;

#define For(i,n) for(int i=0;i<n;i++)
typedef long long LL;
const int MAXN=int(1e5+5);
int n,A,cf,cm;
int a[MAXN],tmp1[MAXN],tmp2[MAXN];
LL s[MAXN],m;

bool cmp(int x,int y){return a[x]<a[y];}

int main(){
    cin>>n>>A>>cf>>cm>>m;
    For(i,n) tmp1[i]=i,cin>>a[i];
    if(!cm && !cf){//坑爹的情况,在force不变时不对数列进行变化
        puts("0");
        For(i,n) cout<<a[i]<<' ';
        return 0;
    }
    sort(tmp1,tmp1+n,cmp);
    sort(a,a+n);
    For(i,n){
        s[i]=a[i];
        i?s[i]+=s[i-1]:0;
    }
    LL ret,ans=0;
    a[n]=A;//特殊情况,即使把所有的m都加到最大数上也不够A
    int _max=0,_min=int(1e9);//_max:A的个数,_min:最小值
    for(int i=n;i>=0;i--){//将i..n-1都变为A
        ret=m-(1ll*A*(n-i)-(s[n-1]-(i?s[i-1]:0)));
        if(ret<0) break;
        if(!cm){//cm==0时不改动最小值
            ans=1ll*(n-i)*cf;
            _max=n-i; _min=0;
            continue;
        }
        LL l=a[0],r=A,mid;//二分最小值
        while(l<r){
            mid=r-((r-l)>>1);
            int k=upper_bound(a,a+n,mid)-a;
            k=min(k,i);
            if(ret>=1ll*k*mid-(k?s[k-1]:0)) l=mid; else r=mid-1;
        }
        LL force=1ll*(n-i)*cf+1ll*l*cm;
        if(force>ans){
            ans=force;
            _max=n-i; _min=l;
        }
    }
    cout<<ans<<endl;
    For(i,n-_max) tmp2[tmp1[i]]=max(_min,a[i]);
    for(int i=n-_max;i<n;i++) tmp2[tmp1[i]]=A;
    For(i,n) cout<<tmp2[i]<<' ';
    return 0;
}

E

题目大意:
给你一些元素,问将他们排成环后,从两个相邻的元素间断开,是否能形成回文串,能的话最多有几种断开方法
题解
计算出现次数为奇数的元素个数odd
若odd>=2,无解
对于其他情况可以对元素进行分组,分成g=gcd(a[i])组,则每组都可构成一个回文串,自然就有g种断开方法,具体看例子吧

e.g.

输入:
3
6 12 6
构造:
分成6组,每组为abbc或cbba
则可构成 abbc cbba abbc cbba abbc cbba
每组后断开就是6种方法

输入:
3
6 9 6
构造:
分成三组,每组为abcbcba
则可构成 abcbcba abcbcba abcbcba
每组后断开就是3种方法

代码:

#include <bits/stdc++.h>
using namespace std;

#define For(i,n) for(int i=0;i<n;i++)
const int MAXN=26;
int n;
int a[MAXN],m=0,odd=0;
char s[int(1e5+5)];

int main(){
    cin>>n;
    For(i,n)
        cin>>a[i],m+=a[i],odd+=a[i]&1;
    if(n==1){
        cout<<m<<endl;
        For(i,m) putchar('a');
        return 0;
    }
    if(odd>=2){
        puts("0");
        For(i,n)
            For(j,a[i])
                putchar('a'+i);
        return 0;
    }
    int g=a[0];
    For(i,n) g=__gcd(g,a[i]);
    printf("%d\n",g);
    int idx=0,nodd=-1;
    For(i,n){
        a[i]/=g;
        if(g&1){
            if(a[i]&1) a[i]=(a[i]-1)>>1,nodd=i;
            else a[i]>>=1;
        }
    }
    For(i,n)
        For(j,a[i])
            s[idx++]='a'+i;
    int k=idx;
    if(nodd!=-1) s[idx++]='a'+nodd;
    For(i,k)
        s[idx++]=s[k-i-1];
    for(int i=idx;i<m;i++)
        s[i]=s[i-idx];
    puts(s);
    return 0;
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看REAdMe.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看READme.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值