Codeforces1079

A.Kitchen Utensils

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN=100+2;
const int MAXK=100+2;
int a[MAXN],c[MAXK],N,K,C,M,Ans;

int main(){
    cin >> N >> K;
    for(int i=1;i<=N;i++){
        cin >> a[i];
        c[a[i]]++,C=max(c[a[i]],C);
    }

    M=C/K;
    if(C%K) M++;

    sort(a+1,a+N+1);
    for(int i=1;i<=N;i++){
        Ans+=M*K-c[a[i]];
        while(a[i+1]==a[i]) i++;
    }
    cout << Ans << endl;

    return 0;
}
View Code

 

B.Personalized Cup

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAXL=200+2;
int a,b,r;
char S[MAXL];
bool Flag;

int main(){
    scanf("%s",S+1);
    for(a=1;a<=5;a++){
        for(b=1;b<=20;b++){
            r=a*b-strlen(S+1);
            if(r>=0){
                Flag=1;
                break;
            }
        }
        if(Flag) break;
    }
    cout << a << " " << b << endl;

    for(int i=1,j=1,k,c=1;i<=a;i++){
        for(k=1;k<=r/a;k++) cout << "*";
        if(c<=r%a) c++,k++,cout << "*";
        while(k<=b) cout << S[j++],k++;
        cout << endl;
    }

    return 0;
}
View Code

 

C.Playing Piano

题意:给定一个序列a,求一个由1~5构成的数列b,满足:b[i]<b[i-1] if a[i]<a[i-1];b[i]>b[i-1] if a[i]>a[i-1];b[i]!=b[i-1] if a[i]==a[i-]1

题解:假如没有第三个条件的话可以贪心,但是有了第三个条件,连续的相等的数应该怎么取就会对后面的产生影响,这时候考虑DP:令f[i][j]表示第i个位置放j是否有解,状态转移显然,DP的时候注意记录一下当前状态可以从哪个状态转移过来。

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN=100000+2;
const int MAXK=5+2;
int N,a[MAXN],g[MAXN][MAXK],Ans[MAXN];
bool f[MAXN][MAXK],Flag;

bool Check(int x,int y,int s,int t){
    if(a[x]<a[y] && s<t) return 1;
    if(a[x]>a[y] && s>t) return 1;
    if(a[x]==a[y] && s!=t) return 1;
    return 0;
}

int main(){
    cin >> N;
    for(int i=1;i<=N;i++) scanf("%d",a+i);

    for(int i=1;i<=5;i++) f[1][i]=1;
    for(int i=2;i<=N;i++)
        for(int j=1;j<=5;j++)
            for(int k=1;k<=5;k++)
                if(f[i-1][k] && Check(i-1,i,k,j)){
                    f[i][j]=1,g[i][j]=k;
                    break;
                }

    for(int i=1;i<=5;i++)
        if(f[N][i]){
            for(int j=N,k=i;j;k=g[j][k],j--) Ans[j]=k;
            Flag=1;
            break;
        }
    if(Flag)
        for(int i=1;i<=N;i++) cout << Ans[i] << " ";
    else cout << -1;
    cout << endl;

    return 0;
}
View Code

 

D.Barcelonian Distance

题意:给定一个曼哈顿图和图上的一条直线,求可以经过该直线的两点之间的最短距离

题解:作垂线,找出四个交点来,然后取距离最小值。

代码:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define exp 1e-8

double a,b,c,X1,Y1,X2,Y2,x[5],y[5],Ans;

double dis(double x1,double y1,double x2,double y2){ return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}

int main(){
    cin >> a >> b >> c >> X1 >> Y1 >> X2 >> Y2;
    x[1]=X1,y[1]=(-a*X1-c)/b;
    x[2]=(-b*Y1-c)/a,y[2]=Y1;
    x[3]=X2,y[3]=(-a*X2-c)/b;
    x[4]=(-b*Y2-c)/a,y[4]=Y2;

    Ans=fabs(X1-X2)+fabs(Y1-Y2);
    Ans=min(Ans,fabs(y[1]-Y1)+fabs(Y2-y[3])+dis(x[1],y[1],x[3],y[3]));
    Ans=min(Ans,fabs(y[1]-Y1)+fabs(X2-x[4])+dis(x[1],y[1],x[4],y[4]));
    Ans=min(Ans,fabs(X1-x[2])+fabs(Y2-y[3])+dis(x[2],y[2],x[3],y[3]));
    Ans=min(Ans,fabs(X1-x[2])+fabs(X2-x[4])+dis(x[2],y[2],x[4],y[4]));
    printf("%.10lf\n",Ans);

    return 0;
}
View Code

 

E.The Unbearable Lightness of Weights

题意:给定一个数,找出n个相同的数a,使得na被唯一表出,求n的最大值

题解:多重背包统计方案数

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN=100+2;
const int MAXA=100+2;
int N,W,C,a[MAXN],f[MAXN][MAXN*MAXA],c[MAXA],Ans;

int main(){
    cin >> N;
    for(int i=1,t;i<=N;i++){
        cin >> t;
        c[t]++,W+=t,C=max(C,c[t]);
    }

    if(N<=2){
        cout << N << endl;
        return 0;
    }
    N=0;
    for(int i=1;i<=100;i++)
        if(c[i]) a[++N]=i,c[N]=c[i];

    f[0][0]=1;
    for(int i=1;i<=N;i++)
        for(int j=W;j;j--)
            for(int k=1;k<=C;k++)
                for(int t=1;t<=k && t<=c[i] && j>=t*a[i];t++)
                    f[k][j]+=f[k-t][j-t*a[i]];

    for(int i=1;i<=N;i++)
        for(int j=1;j<=c[i];j++)
            if(f[j][j*a[i]]==1) Ans=max(Ans,j);
    cout << Ans << endl;

    return 0;
}
View Code

 

F.Vasya and Maximum Matching

(待补)

 

G.Chattering

(待补)

转载于:https://www.cnblogs.com/WDZRMPCBIT/p/10484310.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值