一、题目报告
比赛时,T1暴力得64分,T2得0分,T3 暴力得40分,T4没做得0分,总得分104
二、赛中概况
开始先做的T1,推理了大约40min,推理的时间有点长,又花了50min把代码基本写了一下,但是只对了64分,然后转手做T2。T2写了20min的简单代码,样例对了,造的样例也对,但却一分也没得,就先去看T3、T4了。T4看完之后没有什么很好的思路,就先把T3的代码写完了,但是有三个样例没有对,思考了很久,还是没有想出来,剩余15min时,我就去检查T1、T2、T3了。
三、解题报告
T1.做饭
题目大意:已知达达到家时间是 K 时刻,并且知道当前处在 now 时刻。小可需要 p 秒时间去准备好饭菜。假设小可制作晚饭总共需要 q 秒时间。请问赶在达达到家之前,小可是否能准备完晚饭。
出错地方:这题主要因为我忘记scanf的拼写,而在输入上出错。把”请问赶在达达到家之前“误导为大于等于(t>=x+y)。
出错解析:
1.一开始,没认真读这句话”请问赶在达达到家之前”,认为把时间差大于等于准备饭菜+制作晚饭的时间。
2.输入时因为不知道有冒号,而鼓捣了半天,用完cin,用scanf,可是结构一直都是编译错误。
正解代码
玄学的思路二代码:
#include <bits/stdc++.h>
using namespace std;
long long h1, m1, s1, h2, m2, s2, t, x, y;
int main() {
scanf("%lld:%lld:%lld", &h1, &m1, &s1);
scanf("%lld:%lld:%lld", &h2, &m2, &s2);
scanf("%lld%lld", &x, &y);
t = (h2 * 3600 + m2 * 60 + s2) - (h1 * 3600 + m1 * 60 + s1);
if (t > x + y)
cout << "Yes";
else
cout << "No";
}
T2.评价标准
题目大意:给定一个长度为 n 的数组 S,定义数组 S 的评价标准为:最大值-最小值
。给定一个操作值 k,然后任意从数组中选择一个数字x,可以将数字x 加上 k,或者减去 k,之后得到一个新的数组,并使得新数组的评价标准最小。最终输出最小的评价标准。
出错地方:不知道最小值的三个判断和最大值的三个判断。
出错解析:
1.这道题我把它想得太简单,只把最小值加上k,而没有想最大值,使我的代码才10多行。
正解代码
玄学的思路二代码:
#include <bits/stdc++.h>
#define il inline
#define inf 0x3f3f3f3f
using namespace std;
const int N = 1e6 + 5;
int n, k, a[N];int max1, max2, a1, a2;
int min1, min2, n1, n2;
int nmax, nmin;
int ans = inf;
il void get_ans(int id) {
if (id == a1) {
nmax = max(a[a1], max2);nmin = min(min1, a[id]);
} else
nmax = max(max1, a[id]);
if (id == n1) {
nmin = min(a[n1], min2);nmax = max(max1, a[id]);
} else
nmin = min(min1, a[id]);ans = min(ans, nmax - nmin);
return;
}
signed main() {
scanf("%d %d", &n, &k);k = k < 0 ? -k : k;
min1 = min2 = inf;
max1 = max2 = -inf;
for (int i = 1; i <= n; ++i){
scanf("%d", &a[i]);
if (a[i] > max2) {
if (a[i] > max1) {
a2 = a1;
max2 = max1;
a1 = i;
max1 = a[i];
} else
a2 = i, max2 = a[i];
}
if (a[i] < min2) {
if (a[i] < min1) {
n2 = n1;
min2 = min1;
n1 = i;
min1 = a[i];
} else
n2 = i, min2 = a[i];
}
}
for (int i = 1; i <= n; ++i) {
a[i] -= k;
get_ans(i);
a[i] += k + k;
get_ans(i);a[i] -= k;
}
printf("%d\n", ans);
return 0;
}
在这个基础上,我们可以稍加改进。
简便代码:
#include <bits/stdc++.h>
using namespace std;
int a[10005],b[10005],s[100005],n,k,sum,cnt;
int main() {
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;
b[n]-=k;
sort(a+1,a+n+1);
sort(b+1,b+n+1);
sum=a[n]-a[1];
cnt=b[n]-b[1];
if(sum<cnt){
cout<<sum;
}
else{
cout<<cnt;
}
return 0;
}
T3.小可买菜
题目大意:
小可列了一个购买清单,总共有 n 个食材需要购买,在超市中第 i 个食材的价格是 vi。
今天超市正在进行促销活动,每满两个商品,都可以进行促销活动,使用两个商品中最高价格购买当前这两件商品。
为了节省金钱,小可还在线购买了 k 张超市折扣券,每两件商品可以使用一张折扣券,使用两个商品中最低价格购买当前这两件商品。
注意:商品不能重复参加活动。
请问小可购买清单中所有物品都购买后,最低花费多少元。
出错地方:不知道这个问题是双指针的问题,而用暴力运算得了40分。
出错解析:1.在这个问题中,我想把最大的和次大用了折扣券,而不考虑最小的和次小的问题。
正解代码
玄学的思路二代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
long long n, k, ans, a[N];
int main() {
cin >> n >> k;
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
sort(a + 1, a + n + 1);
for (int l = 1, r = n; l <= r;) {
if (k > 0) {
ans += a[l];
l++, r--, k--;
}
else {
ans += a[r];
r -= 2;
}
}
cout << ans;
return 0;
}
T4.美味佳肴
题目大意:
小可为了让达达吃起来最顺利,已经给食物提前进行了标记,标记分为两种:大写字母
和 ?
,相同大写字母表示两个食物搭配起来吃最美味,?
则表示搭配任何一个食物吃都非常美味,但是达达有习惯,一旦使用当前这种食物搭配另一个食物,达达就不会再去搭配其他食物吃,也就是说每个?
确定与某个食物搭配后,则不能再与其他食物搭配食用。
现在请问小可制作的饭菜中最多有多少种不同的搭配。
注意:
不同的搭配表示,字符相等,但是位置不同。
形式化的讲,给定一个由大写字母
和?
构成的字符串 s ,在字符串中存在 l,r 满足 l<r 且 s[l]==s[r],则表示一种美味搭配。找出最多的不同的搭配,当 l 不同或 r 不同,就表示一种不同搭配。
出错地方:不会用等差数列求和公式。
出错解析:1.这题中,我想的是用27个判断记录字母出现的次数和双层循环,导致时间运行很慢,
把Dev-c++给卡爆了。写了很长,但用处不大,白白浪费时间。
正解代码
玄学的思路二代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
string s;
long long T, ans, num, maxx, pos, a[30];
int main() {
cin >> T;
while (T--) {
cin >> s;
ans = 0, num = 0, maxx = 0, pos = 0;
for (int i = 0; i < 26; i++) {
a[i] = 0;
}
for (int i = 0; i < s.length(); i++) {
if (s[i] == '?') {
num++;
} else {
a[s[i] - 'A']++;
}
}
for (int i = 0; i < 26; i++) {
if (a[i] > maxx) {
maxx = a[i];
pos = i;
}
}
a[pos] += num;
for (int i = 0; i < 26; i++) {
ans += a[i] * (a[i] - 1) / 2;
}
cout << ans << endl;
}
reutrn 0;
}
4.总结
这次模拟赛中,我考了104分,主要因为我不读题,忘记以前的知识(scanf)。最重要的是我有是把代码想的过于简单,看起来对了,但因为步骤分没拿到。有时代码想的过于复杂,写了很长的代码,但一点也没对,浪费了很长时间,才导致只有两个题做了。