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; }