Codeforces Round #852 (Div. 2)
文章目录
A. Yet Another Promotion
题目大意
你想买n公斤土豆吃一个月。你知道在这个月的第一天,1 k土豆的价格是a个硬币,第二天是b个硬币,可以买到任意整数公斤的土豆。幸运的是,“第二食物”宣布了土豆促销活动,仅在每月的第一天有效——每购买m公斤土豆,就可以获得1公斤的礼物!换句话说,你可以通过支付m公斤来获得m + 1公斤。求出购买至少n公斤土豆所需的最小硬币数。
题目分析
可以分成两部分进行讨论:当a>=b
时,全买第一天的肯定是花费最少的;当a>b
时要从全麦第二天的和混搭的取最小值。
code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, m, k, t, a, b;
void solve()
{
cin >> a >> b >> n >> m;
if(a <= b)
{
if(m >= n) cout << a * n << "\n";
else
{
ll res = n / (m + 1);
ll tem = n - res * (m + 1);
cout << (tem + res * m) * a << "\n";
}
}
else
{
ll res = n / (m + 1);
ll tem = n - res * (m + 1);
cout << min(res * m * a + tem * b, b * n) << "\n";
}
}
signed main()
{
cin >> t;
while(t --) solve();
return 0;
}
B. Fedya and Array
题目大意
数组a,数组中有n个整数排成一个圆圈。对于每一对相邻的数字它们之间的绝对差值等于1。我们称局部极大值为一个元素,它大于它的两个相邻元素。也称局部最小值为元素,它小于相邻的两个元素。不幸的是,Fedya丢失了一个数组,但他记得其中局部最大值x和局部最小值y的和。给定x和y,帮助Fedya找到最小长度的匹配数组。
题目分析
峰值和谷值之和应该是唯一的与峰值和谷值数量无关,可以看作一个折线图。
所以我们只需要构造一个峰一个谷的序列即可满足要求,峰值和谷值分别为所给的x
和y
,峰值和谷值之间需要其他数连接起来,则需要2*(x-y)
个数
code
#include <bits/stdc++.h>
using namespace std;
int n, m, k, t;
void solve()
{
cin >> n >> m;
k = n - m;
cout << k * 2<< endl;
for(int i = n; i >= m; i --) cout << i <<" ";
for(int i = m + 1; i < n; i ++) cout << i << " ";
puts("");
}
signed main()
{
cin >> t;
while(t --) solve();
return 0;
}
C. Dora and Search
题目大意
有一个排列,想找到这样一个子段,它的末尾的元素都不是整个子段的最小值或最大值。.长度为n的排列是由n个从1到n的不同整数以任意顺序组成的数组。帮助Dora找到这样的子段,或者告诉她这样的子段不存在。
题目分析
从两边往中间按要求找即可,当存在一对数数值与索引相同时一定不满足则需要继续找。
code
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, m, k, t;
int a[N];
void solve()
{
cin >> n;
for(int i = 1; i <= n; i ++) cin >> a[i];
int l = 1, r = n, p = 1, q = n;
while(p < q)
{
if(a[p] == l) p ++, l ++;
else if(a[p] == r) p ++, r --;
else if(a[q] == l) q --, l ++;
else if(a[q] == r) q --, r --;
else
{
cout << p << " " << q << "\n";
return;
}
}
puts("-1");
}
int main()
{
cin >> t;
while(t --) solve();
return 0;
}