一、题目报告
比赛中第一题90分(9组数据),第二题0分,第三题40分(4组数据),第四题30分(3组数据),比赛后全部AC。
二、赛中概况
首先做的第一题,把思路想麻烦了,忘记了scanf,写了70多行非常繁琐,用了40分钟左右。然后做了二题,第二题把思路想简单了,但也用了不少时间,用了40分钟。然后是第三题,发现存储空间不够,忘记放全局,最后预估拿到40%的分。最后一题题目没有理解,只能满足30%的情况,做了50分钟左右,由于少了一些情况,只拿到30分。
三、题目正解
T1.做饭()
题目情况
比赛时90分,比赛后AC。
题目大意
给定起始时间和结束时间,求经过p+q的时间会不会在结束时间之前。
题目解析
首先观察题目,最简便的方法是把时间全部转换成秒数
(1)因为题目要求10的8次方,乘3600后会溢出所以改为double类型
(2)题目要输入冒号,所以用scanf
(3)把所有数据换成秒,更好算
(4)在之前,所以是大于
正解代码
#include<iostream>
#include<cstdio>
using namespace std;
long long p,q,h1,m1,s1,h2,m2,s2;
int main(){
freopen("cook.in","r",stdin);
freopen("cook.out","w",stdout);
scanf("%lld:%lld:%lld",&h1,&m1,&s1);
scanf("%lld:%lld:%lld",&h2,&m2,&s2);
cin>>p>>q;
long long t=(h2*3600+m2*60+s2)-(h1*3600+m1*60+s1);
if(t>p+q) cout<<"Yes";
else cout<<"No";
fclose(stdin);
fclose(stdout);
return 0;
}
T2.评价标准()
题目情况
比赛时0分,比赛后AC。
题目大意
定义数组 的评价标准为: 最大值-最小值 。
给定一个操作值k,然后任意从数组中选择一个数字 ,可以将数字x加上k,或者减去k,之后得到一个新的数组,并使得新数组的评价标准最小。最终输出最小的评价标准。
题目解析
观察题目,因为为了使评价标准最小,所以只能对最大值和最小值进行操作
- 首先对序列进行排序
- 分别列举情况,最小值+k或者最大值-k后进行再次排序
- 比较出最小值
正解代码
代码在此!!!!
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int n,k,s[10000005],a[10000005],b[10000005],sum1=0,sum2=0;
int main(){
freopen("criterion.in","r",stdin);
freopen("criterion.out","w",stdout);
cin>>n>>k;
k=abs(k);
for(int i=1;i<=n;i++){
cin>>s[i];
a[i]=s[i];
b[i]=s[i];
}
sort(a+1,a+n+1);
sort(b+1,b+n+1);
a[1]+=k;
sort(a+1,a+n+1);
b[n]-=k;
sort(b+1,b+n+1);
sum1+=a[n]-a[1];
sum2+=b[n]-b[1];
cout<<min(sum1,sum2);
fclose(stdin);
fclose(stdout);
return 0;
}
T3.小可买菜()
题目情况
比赛时40分,比赛后AC。
题目大意
共有n个食材需要购买,在超市中第i个食材的价格是v[i] 。
超市正在进行促销活动,每满两个商品,都可以进行促销活动,使用两个商品中最高价格购买当前这两件商品。
小可还在线购买了k张超市折扣券,每两件商品可以使用一张折扣券,使用两个商品中最低价格购买当前这两件商品。
注意:商品不能重复参加活动。
请问小可购买清单中所有物品都购买后,最低花费多少元。
题目解析
观察题目,因为为了使花费最小,所以用优惠券低价格带高价格,用折扣一大带一大。
- 排序
- 用双指针
正解代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
long long n,k,a[1000005],ans;
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+n+1);
int l=1,r=n;
while(l<=r){
if(k>0){
ans+=a[l];
l++,r--,k--;
}else{
ans+=a[r];
r-=2;
}
}
cout<<ans;
fclose(stdin);
fclose(stdout);
return 0;
}
T4.美味佳肴()
题目情况
比赛时30分,比赛后AC。
题目大意
标记分为两种: 大写字母 和 ? ,相同大写字母表示两个食物搭配起来吃最美味, ? 则表示搭配任何一个食物吃都非常美味,但是达达有习惯,一旦使用当前这种食物搭配另一个食物,达达就不会再去搭配其他食物吃,也就是说每个 ? 确定与某个食物搭配后,则不能再与其他食物搭配食用。
现在请问小可制作的饭菜中最多有多少种不同的搭配。注意:不同的搭配表示,字符相等,但是位置不同。
形式化的讲,给定一个由 大写字母 和 ? 构成的字符串 ,在字符串中存在 满足 且,则表示一种美味搭配。找出最多的不同的搭配,当 不同或 不同,就表示一种不同搭配。
题目解析
观察题目,因为要求最多搭配,?可以成为任意字母,所以尽量加到最多的字母上。
- 桶标记
- 每个字母都用等差数列求和
正解代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int main(){
long long n,a[95]={0},max2=0,sum=0,w=0;
string s;
cin>>n;
while(n--){
memset(a,0,sizeof a);
cin>>s;
w=sum=max2=max1=0;
for(int i=0;i<s.size();i++){
if(s[i]=='?'){
w++;
}else{
a[s[i]-'A']++;
}
}
for(int i=0;i<=25;i++){
if(a[i]>max1){
max2=i;
}
}
a[max2]+=w;
for(int i=0;i<=25;i++){
sum+=((a[i]-1)*a[i]/2);
}
cout<<sum<<endl;
}
return 0;
}
总结
整体做的不太好,发现很多问题,动手做题能力有待提高
注意事项:
1.scanf输入更简便,如:scanf("%d:%d",h,min);可以输入一个时刻,而且能得到两个int类型的时与分
2.函数内部数组最多开到10的5次方左右,如果定义全局可以开到10的6次方左右
3.不开long long见祖宗,如果无法判断大小那么最保险开long long 类型
4.最好不要用万能头,实在不记得了再用
5.freopen必备头文件:include<cstdio>
6.不要忘记框架,代码如下:
#include<iostream>
using namespace std;
int main(){
freopen("in1.in","r",stdin);
freopen("out1.out","w",stdout);
代码
fclose(stdin);
fclose(stdout);