弱鸡儿长乐爆零旅Day3

T1奶牛晒衣服

【问题描述】

    在熊大妈英明的带领下,时针和他的同伴生下了许多牛宝宝。熊大妈决定给每个宝宝都穿上可爱的婴儿装。于是,为牛宝宝洗晒衣服就成了很不爽的事情。

    圣人王担负起了这个重任。洗完衣服后,你就要弄干衣服。衣服在自然条件下用1的时间可以晒干A点湿度。抠门的熊大妈买了1台烘衣机。使用烘衣机可以让你用1的时间使1件衣服除开自然晒干的A点湿度外,还可烘干B点湿度,但在1的时间内只能对1件衣服使用。

    N件的衣服因为种种原因而不一样湿,现在告诉你每件衣服的湿度,要你求出弄干所有衣服的最少时间(湿度为0为干)。

【输入格式】

    第一行N,A,B,接下来N行,每行一个数,表示衣服的湿度(1<=湿度,A,B<=500000,1<=N<=500000)。

【输出格式】

    一行,最少时间。

【输入样例】Dry.in

    3 2 1

    1

    2

    3

【输出样例】Dry.out

    1

样例解析】

    第1个时间内,用机器处理第3件衣服,此外,所有衣服自然晒干2。花费1时间全部弄干。

优先队列做法

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
priority_queue<int>q;
inline int read()
{
    int f=0;
    char ch=getchar();
    while(ch>'9' || ch<'0')
        ch=getchar();
    while(ch>='0' && ch<='9'){
        f=f*10+ch-'0';
        ch=getchar();
    }
    return f;
}
int n,a,b;
int main()
{
    freopen("Dry.in","r",stdin);
    freopen("Dry.out","w",stdout);
    n=read();a=read();b=read();
    for(int i=1;i<=n;i++){
        int x=read();
        q.push(x);
    }
    int i;
    for(i=0;;++i){
        int x=q.top();q.pop();
        if(x-a*i<=0) break;
        else if(x-b>0)q.push(x-b);
    }
    printf("%d",i);
    return 0;
}

O(n)算法

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
inline int read()
{
    int f=0;
    char ch=getchar();
    while(ch>'9' || ch<'0')
        ch=getchar();
    while(ch>='0' && ch<='9'){
        f=f*10+ch-'0';
        ch=getchar();
    }
    return f;
}
int n,a,b;
int cnt[500010];
int main()
{
    int mx=-1;
    n=read();a=read();b=read();
    for(int i=1;i<=n;i++){
        int x=read();
        cnt[x]++;
        mx=max(mx,x);
    }
    int t=0;
    while(t*a<mx){
        t++;
        if(mx-b>0)cnt[mx-b]++;
        cnt[mx]--;
        while(!cnt[mx])mx--;
    }
    printf("%d",t);
    return 0;
}

T2解密文本

【问题描述】

    已知英语中26个字母出现的概率p[0],p[1]……,p[25](它们的和为1),分别表示’a’, ‘b’,‘c’……出现的概率(大写字母和小写字母被认为是一样的)。

    现在有一个加密过的文件,加密方法是将原文件中的每一个字母进行相同的变换,其他的字符不变,变换的方法如下:

    如果将a到z编号为0到25,那么字母i将被替换成(i+k) mod 26,0<=k<26。原来是大写的字母,仍然是大写,原来是小写的字母仍然是小写。

    但是你并不知道k的值,所以只好枚举。因为知道26个字母出现的频率,所以你可以选择一个尽量好的k,使得频率的方差和最小,方差和定义如下:

    假设你枚举的k还原出来的原文件中的26个字母出现的概率为x[0], x[1], ……, x[25],那么方差和为:(p[0]-x[0])^2 + (p[1]-x[1])^2 + …… + (p[25]-x[25])^2

    如果有两个相同的k一样好,那么选较小的k

    最后输出解密出的原文件。

【输入格式】

    前26行分别是26个字母出现的概率。

    接下来是一个只含有26个大小写字母和空格,换行符,标点符号,阿拉伯数字等的文本。

【输出格式】

    解密过的文本。

【输入样例】

0.109375

0.000000

0.062500

0.015625

0.109375

0.015625

0.015625

0.000000

0.062500

0.015625

0.000000

0.078125

0.062500

0.062500

0.093750

0.015625

0.015625

0.031250

0.046875

0.046875

0.046875

0.000000

0.000000

0.000000

0.093750

0.000000

L dp Ol Bxtldq, ru brx fdq fdoo ph VsdfhIobhu.

L dp jodg wr vhh brx.

Hqmrb pb frqwhvw.

【输出样例】

I am Li Yuqian, or you can call me SpaceFlyer.

I am glad to see you.

Enjoy my contest.

分析:处理数据 枚举 完事

xjh:T2不是很简单吗

TvTvTvTvT

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
const int mod=26;
string s[1005];
double x[30];
double oc[30],sum1;
//oc记录字符串中字母出现次数 
int tot;
struct rex{
    double p;
}p[26];
struct rec{
    string s;
    int len;
    int bo[10000];//小写0 大写1 符号2 
}qaq[1005];
double sq()
{
    double w=0;
    for(int i=0;i<26;i++)
        w+=(p[i].p-x[i])*(p[i].p-x[i]);
    return w;
}
int main()
{
    //freopen("decode.in","r",stdin);
    //freopen("decode.out","w",stdout);
    for(int i=0;i<26;i++){
        scanf("%lf\n",&p[i].p);//(-_-|||)  不
        //(-_-|||)  写
        //(-_-|||)  换
        //(-_-|||)  行
        //(-_-|||)  会
        //(-_-|||)  爆
        //(-_-|||)  零
    }
    while(getline(cin,s[++tot])){
        qaq[tot].s=s[tot];
        int len=qaq[tot].len=s[tot].length();
        for(int i=0;i<len;i++){
            if(s[tot][i]>='a' && s[tot][i]<='z'){
                oc[s[tot][i]-'a']++;
                qaq[tot].bo[i]=0;
            }
            else if(s[tot][i]>='A'&&s[tot][i]<='Z'){
                oc[s[tot][i]-'A']++;
                qaq[tot].bo[i]=1;
            }
            else qaq[tot].bo[i]=2;
        }    
    }
    for(int i=0;i<26;i++)
        sum1+=oc[i];
    int ak=0;
    double sq1=999999999999;
    for(int k=0;k<26;k++){
        for(int i=0;i<26;i++)
            x[i]=oc[(i+k)%26]/sum1;
        if(sq1>sq()){
            sq1=sq();
            ak=k;
        }
    }
    for(int i=1;i<tot;i++){
        int len=qaq[i].len;
        for(int j=0;j<len;j++){
            char ch=qaq[i].s[j];
            if(qaq[i].bo[j]==2) cout<<ch;
            else if(qaq[i].bo[j]==0){
                cout<<(char)((ch-'a'-ak+52)%26+'a');
            }
            else if(qaq[i].bo[j]==1){
                cout<<(char)((ch-'A'-ak+52)%26+'A');
            }
        }
        cout<<endl;
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/WJill/p/11240760.html