可恶的coduck,还我妈生假期!!!
一 ,考试分数
第一题90分,第二,三题40分,第四题0分(已补题),总分170分。
二,内心历程
在做题的时候,我先做了第一题,我用了一个调整时间的方法,但是方法不对,被hack了,拿了90分;然后我先做了第三题,因为第二题我还没有思路,我的想法是对的,但是写代码是想复杂了,所以才拿了40分;接着,我开始写第二题,我直接奔着40分去的,我自己都认为会时间超限,结果也不出所料;最后,我才看得第四题,我是一点也没有思路,直接打了个暴力,一分不得。
三,题目分析
T1.做饭
问题描述
小可对达达真的是真爱!
小可为了体现对达达的爱,特意要为即将下班的达达做一顿丰富的晚饭!
已知达达到家时间是 KK 时刻,并且知道当前处在 now 时刻。
小可需要 pp 秒时间去准备好饭菜。
假设小可制作晚饭总共需要 qq 秒时间。
请问赶在达达到家之前,小可是否能准备完晚饭。(注意,是之前!)
输入格式
输入第一行按照 hh : mm : ss
,即时:分:秒
表示的时间 nownow,表示当前时间。
输入第二行按照 hh : mm : ss
,即时:分:秒
表示的时间 KK,表示达达到家的时刻。
输入第三行两个整数 p,qp,q,分别表示准备时间和制作时间。
输出格式
如果可以赶在达达回家之前制作完晚饭,输出Yes
,否则输出No
。
这个题主要是都算出所代表的秒是多少,再比较,也可以暴力,不过要注意数据范围。
90分代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
using namespace std;
long long kxs,kfz,km,dxs,dfz,dm,p,q;
int main() {
// freopen("cook.in","r",stdin);
// freopen("cook.out","w",stdout);
scanf("%lld:%lld:%lld",&kxs,&kfz,&km);
scanf("%lld:%lld:%lld",&dxs,&dfz,&dm);
scanf("%lld%lld",&p,&q);
long long pq=p+q;
if(pq+km<60) {
km+=pq;
} else {
p=pq;
pq=(pq+km)/60;
km=(p+km)%60;
if(kfz+pq<60) {
kfz+=pq;
} else {
p=pq;
pq=(pq+kfz)/60;
kfz=(kfz+p)%60;
kxs+=pq;
}
}
// printf("%d %d %d\n",kxs,kfz,km);
if(kxs>dxs) {
cout<<"No";
} else if(kxs==dxs&&kfz>dfz) {
cout<<"No";
} else if(kxs==dxs&&kfz==dfz&&km>dm) {
cout<<"No";
} else {
cout<<"Yes";
}
// fclose(stdin);
// fclose(stdout);
return 0;
}
100分代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
using namespace std;
long long kxs,kfz,km,dxs,dfz,dm,p,q;
int main() {
// freopen("cook.in","r",stdin);
// freopen("cook.out","w",stdout);
scanf("%lld:%lld:%lld",&kxs,&kfz,&km);
scanf("%lld:%lld:%lld",&dxs,&dfz,&dm);
scanf("%lld%lld",&p,&q);
long long sum=(kxs*3600+kfz*60+km)-(dxs*3600+dfz*60+dm);
if(sum>q+p){
cout<<"Yes";
}else{
cout<<"No";
}
// fclose(stdin);
// fclose(stdout);
return 0;
}
一个23行的代码,我写了43行,还错了,无语。
T2.评价标准
问题描述
给定一个长度为 nn 的数组 SS ,其中包含S_1,S_2,\cdots,S_nS1,S2,⋯,Sn。
定义数组 SS 的评价标准为:最大值-最小值
。
小可同学觉得问题过于简单。然后定义了一种操作:给定一个操作值 kk,然后任意从数组中选择一个数字xx,可以将数字 xx 加上 kk,或者减去 kk,之后得到一个新的数组,并使得新数组的评价标准最小。最终输出最小的评价标准。
输入格式
输入第一行包含两个整数 n,k 。
第二行输入数组 SS,总共 nn 个整数,使用空格分开。
输出格式
输出一行,包含一个整数,表示操作后最小的评价标准。
这个题主要就是比较所有的情况,打一个暴力,再进行优化。
40分代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#define endl "\n"
using namespace std;
const int N=1e6+10;
int n,k,a[N],mix[N<<1]= {N},maxx1,minn1=N,man=N,maxx2,minn2=N;
int main() {
// freopen("crirerion.in","r",stdin);
// freopen("crirerion.out","w",stdout);
cin>>n>>k;
for(int i=1; i<=n; i++) {
cin>>a[i];
}
for(int i=1; i<=n; i++) {
a[i]+=k;
minn1=N;
maxx1=0;
for(int j=1; j<=n; j++) {
// printf(" %d ",a[j]);
maxx1=max(maxx1,a[j]);
minn1=min(minn1,a[j]);
}
// cout<<endl;
a[i]-=k;
a[i]-=k;
minn2=N;
maxx2=0;
for(int j=1; j<=n; j++) {
// printf(" %d ",a[j]);
maxx2=max(maxx2,a[j]);
minn2=min(minn2,a[j]);
}
a[i]+=k;
// cout<<endl;
mix[i]=min((maxx1-minn1),(maxx2-minn2));
}
for(int i=1; i<=n; i++) {
// printf("==%d==",mix[i]);
man=min(man,mix[i]);
}
cout<<man;
// fclose(stdin);
// fclose(stdout);
return 0;
}
暴力写法
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#define endl "\n"
using namespace std;
const int N=1e6+10,M=0x3f3f3f3f;
int n,k,s[N],maxx=-M,cmax=-M,minn=M,cmin=M,ans=0;
int main() {
// freopen("crirerion.in","r",stdin);
// freopen("crirerion.out","w",stdout);
cin>>n>>k;
k=abs(k);
for(int i=1;i<=n;i++){
cin>>s[i];
maxx=max(maxx,s[i]);
minn=min(minn,s[i]);
}
ans=maxx-minn;
int c1=0,c2=0;
for(int i=1;i<=n;i++){
if(s[i]==minn) c1++;
if(s[i]==maxx) c2++;
if(s[i]!=minn&&s[i]<cmin){
cmin=s[i];
}
if(s[i]!=maxx&&s[i]>cmax) cmax=s[i];
}
if(c1>1&&c2>1){
cout<<ans;
return 0;
}
if(c1==1&&c2>1){
int t=k+minn;
if(t>=minn&&t<maxx){
ans=min(ans,maxx-cmin);
}else if(t<cmin){
minn=minn+k;
ans=min(ans,maxx-minn);
}else if(t>=maxx){
maxx=t;
ans=min(ans,maxx-cmin);
}
}else if(c2==1&&c1>1){
int t=maxx-k;
if(t<=maxx&&t>minn){
ans=min(ans,cmax-minn);
}else if(t<cmin){
maxx=t;
ans=min(ans,maxx-minn);
}else if(t<=minn){
minn=t;
ans=min(ans,cmax-minn);
}
}else{
if(k+minn<cmin){
minn=k+minn;
ans=min(ans,maxx-minn);
}
if(k+minn>=cmin&&k+minn<maxx){
ans=min(ans,maxx-cmin);
}
if(k+minn>=maxx){
maxx=k+minn;
ans=min(ans,maxx-cmin);
}
if(maxx-k>cmax){
maxx=maxx-k;
ans=min(ans,maxx-minn);
}
if(maxx-k<=cmax&&maxx-k>minn){
ans=min(ans,cmax-maxx);
}
if(maxx-k<=minn){
minn=maxx-k;
ans=min(ans,cmax-minn);
}
}
cout<<ans;
// fclose(stdin);
// fclose(stdout);
return 0;
}
优化后
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#define endl "\n"
using namespace std;
const int N=1e6+10,M=0x3f3f3f3f;
int n,k,a[N],b[N],sum1,sum2;
int main() {
// freopen("crirerion.in","r",stdin);
// freopen("crirerion.out","w",stdout);
cin>>n>>k;
k=abs(k);
for(int i=1;i<=n;i++){
cin>>a[i];
b[i]=a[i];
}
sort(a+1,a+1+n);
sort(b+1,b+1+n);
a[1]+=k;
b[n]-=k;
sort(a+1,a+1+n);
sort(b+1,b+1+n);
sum1=a[n]-a[1];
sum2=b[n]-b[1];
cout<<min(sum1,sum2);
// fclose(stdin);
// fclose(stdout);
return 0;
}
老师非让我们把暴力写上,要死了啊啊啊!!!!!
T3.小可买菜
问题描述
小可对达达真的是真爱!
小可为了体现对达达的爱,特意要为即将下班的达达做一顿丰富的晚饭!
做饭之前需要先购买足够的新鲜的食材,小可来到了超市。
小可列了一个购买清单,总共有 n个食材需要购买,在超市中第 i 个食材的价格是 v_i。
今天超市正在进行促销活动,每满两个商品,都可以进行促销活动,使用两个商品中最高价格购买当前这两件商品。
为了节省金钱,小可还在线购买了 k 张超市折扣券,每两件商品可以使用一张折扣券,使用两个商品中最低价格购买当前这两件商品。
注意:商品不能重复参加活动。
请问小可购买清单中所有物品都购买后,最低花费多少元。
输入格式
第一行输入两个整数 n,k,含义如题所示。
第二行输入 n 个整数 v_i,数字以空格分隔,表示每个食材价格。
输出格式
输出一行包含一个整数,表示小可购买清单中所有物品都购买后,最低花费多少元。
这里使用了一个双指针的思想,先用掉k张折扣卷,用最便宜的价格买最贵的,没折扣卷后买两个价格差不多的,累加起来。看起来不难,其实也挺简单。上代码!
40分代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1e6+10;
int n,k,a[N];
int main() {
// freopen("buy.in","r",stdin);
// freopen("buy.out","w",stdout);
cin>>n>>k;
for(int i=1; i<=n; i++) {
cin>>a[i];
}
sort(a+1,a+1+n);
int i=1,j=n,f=n-1;
while(i<j) {
if(k>0) {
a[j]=0;
k--;
i++;
j--;
f--;
} else {
a[f]=0;
f-=2;
j-=2;
}
}
int sum=0;
for(int ii=1; ii<=n; ii++) {
sum+=a[ii];
}
cout<<sum;
// fclose(stdin);
// fclose(stdout);
return 0;
}
100分代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1e6+10;
long long n,k,a[N];
int main() {
// freopen("buy.in","r",stdin);
// freopen("buy.out","w",stdout);
cin>>n>>k;
for(int i=1; i<=n; i++) {
cin>>a[i];
}
sort(a+1,a+1+n);
long long l=1,r=n,sum=0;
while(k--&&l<=r){
sum+=a[l];
l++;
r--;
}
while(l<=r){
sum+=a[r];
r-=2;
}
cout<<sum;
// fclose(stdin);
// fclose(stdout);
return 0;
}
这个题错还是错在了不应该定义f指针,导致错误,也是样例测试的不够多。
T4.美味佳肴
问题描述
吃面包要配果酱
吃薯条要配番茄酱
。。。
达达发现,小可准备的这些美食中,很多食物搭配起来吃最美味了!
小可为了让达达吃起来最顺利,已经给食物提前进行了标记,标记分为两种:大写字母和 ?
,相同大写字母表示两个食物搭配起来吃最美味,?
则表示搭配任何一个食物吃都非常美味,但是达达有习惯,一旦使用当前这种食物搭配另一个食物,达达就不会再去搭配其他食物吃,也就是说每个?
确定与某个食物搭配后,则不能再与其他食物搭配食用。
现在请问小可制作的饭菜中最多有多少种不同的搭配。
注意:
不同的搭配表示,字符相等,但是位置不同。
形式化的讲,给定一个由大写字母
和?
构成的字符串 s ,在字符串中存在 l,r 满足 l < r 且 s[l] == s[r],则表示一种美味搭配。找出最多的不同的搭配,当 l 不同或 r 不同,就表示一种不同搭配。
输入格式
多组测试,第一行一个整数 T,表示测试组数。
然后对于每组测试数据,输入一个字符串s,含义如题所示。
输出格式
对于每组测试数据,输出一个整数,表示不同的搭配数量。
这个题是用一个桶来存下最多的大写字母,然后利用等差数列求和公式,算出答案。
100分代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=1e6+10;
long long a[95],t;
string s;
int main() {
// freopen("buy.in","r",stdin);
// freopen("buy.out","w",stdout);
cin>>t;
while(t--){
memset(a,0,sizeof a);
cin>>s;
int maxx=0;
long long ans=0;
int len=s.size();
int temp;
for(int i=0;i<len;i++){
a[s[i]]++;
if(s[i]!='?'){
if(a[s[i]]>maxx){
maxx=a[s[i]];
temp=s[i];
}
}
}
if(a['?']==0){
for(int j=65;j<=90;j++){
ans+=a[j]*(a[j]-1)/2;
}
}else{
a[temp]+=a['?'];
for(int j=65;j<=90;j++){
ans+=a[j]*(a[j]-1)/2;
}
}
cout<<ans<<endl;
}
// fclose(stdin);
// fclose(stdout);
return 0;
}
四,总结
这次模拟成绩并不是很好,所以以后还是得多加练习,并保证不会出现操作性的问题。