A. Parkway Walk
翻译:
你正穿过你家附近的一条公园路。公园里有n+1个长椅,从左到右依次编号为1到n+1。长椅i和i+1之间的距离是ai米。
最初,你有m个单位的能量。要走1米的距离,你要花费1单位的能量。如果你没有能量,你就不能行走。另外,你可以通过坐在长椅上来恢复你的能量(这也是恢复能量的唯一方法)。当你坐着的时候,你可以恢复你想要的任何整数的能量(如果你坐的时间长,你恢复的能量就多)。请注意,你的能量量可以超过m。
你的任务是找到你必须恢复的最小能量量(通过坐在长椅上),以便从长椅1到达长椅n+1(并结束你的行走)。
思路:一个签到题,求出从长椅1到长椅n+1需要多少能量,然后减去初始的能量即可。
需要注意的是根据样例,当初始的能量足以从开始走到末尾,则输出0
/*
author : Mzx
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> PII;
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define x first
#define y second
int read () {
int k=0,f=1;
char c=getchar ();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar ();}
while (c>='0'&&c<='9') {k=k*10+c-'0';c=getchar ();}
return k*f;
}
void solve()
{
int n,m;cin>>n>>m;
int num = 0;
for(int i = 1;i<=n;i++)
{
int x;cin>>x;
num+=x;
}
if(num >= m) cout<<num-m<<endl;
else cout<<'0'<<endl;
}
int main()
{
ios;
int t; cin>>t;
while(t--)
{
solve();
}
return 0;
}
B. Promo
翻译:
商店出售n种商品,第i种商品的价格为pi。商店的管理层将举行一次促销活动:如果顾客至少购买了x件商品,其中最便宜的y件将免费。
管理层还没有决定x和y的具体数值。因此,他们要求你处理q个查询:对于给定的x和y的数值,如果顾客购买一次,确定免费获得的物品的最大总价值。
请注意,所有的查询都是独立的;它们不影响商店的库存。
思路:
对p数组进行排序,找到需要买的n个中的k个最小值之和,用前缀和来维护总的价值和,因为是从大到小排序的,所有最后用s[x] - s[x - y]即为我们所求的答案。
/*
author : Mzx
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> PII;
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;
const int maxn = 2e5+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define x first
#define y second
int read () {
int k=0,f=1;
char c=getchar ();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar ();}
while (c>='0'&&c<='9') {k=k*10+c-'0';c=getchar ();}
return k*f;
}
bool cmp(int a,int b)
{
return a > b;
}
ll p[maxn];
ll s[maxn];
int main()
{
int n,m;
while (scanf("%d%d",&n,&m)!=EOF)
{
memset(s,0,sizeof s);
for(int i = 1;i <= n;i++) scanf("%lld",&p[i]);
sort(p + 1,p + n + 1,cmp);
for(int i = 1;i<=n;i++) s[i] = p[i]+s[i-1];
while(m--){
int x, y;
scanf("%d%d",&x,&y);
ll num = 0;
num += s[x] - s[x - y];
printf("%lld\n",num);
}
}
return 0;
}
C. awoo’s Favorite Problem
翻译:
给你两个长度为n的字符串s和t,两个字符串中的每个字符都是’a’、‘b’或’c’。
在一次行动中,你可以执行以下行动之一。
1.选择s中出现的一个 “ab”,用 "ba "代替它。
2.选择s中出现的 “bc”,然后用 "cb "替换它。
你被允许执行任意数量的动作(可能是零)。你能改变字符串s以使其等于字符串t吗?
思路:
从两次的行动中,我们可以看出,a字符只能向后移动,而c字符只能向前移动,而b字符的位置对我们答案无贡献,所以只需要比较每一次在s和t字符串出现的a和c的位置,即可得出答案。(需要特判在移动前,两个数组a,b,c这三个字符的数量是否相等,若不相等则直接返回false)
/*
author : Mzx
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> PII;
const ll mod=1e9+7;
const int INF=0x3f3f3f3f;
const int maxn=1e5+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define x first
#define y second
int read () {
int k=0,f=1;
char c=getchar ();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar ();}
while (c>='0'&&c<='9') {k=k*10+c-'0';c=getchar ();}
return k*f;
}
void solve(){
int T; cin >> T;
while(T --) {
int n;
string s, t;
bool ok = true;
cin >> n >> s >> t;
string s2 = "", t2 = "";
for (int i = 0; i < n; i++) {
if (s[i] != 'b')s2.push_back(s[i]);
if (t[i] != 'b')t2.push_back(t[i]);
}
if (s2 != t2) {
cout << "NO" << endl;
continue;
}
vector<ll> sc, tc;
for (int i = 0; i < n; i++) {
if (s[i] == 'c')sc.push_back(i);
if (t[i] == 'c')tc.push_back(i);
}
for (int i = 0; i < sc.size(); i++) {
if (sc[i] < tc[i]) {
ok = false;
break;
}
}
vector<ll> sa, ta;
for (int i = 0; i < n; i++) {
if (s[i] == 'a')sa.push_back(i);
if (t[i] == 'a')ta.push_back(i);
}
for (int i = 0; i < sa.size(); i++) {
if (sa[i] > ta[i]) {
ok = false;
break;
}
}
if (ok)cout << "YES" << endl;
else cout << "NO" << endl;
}
}
int main(){
ios;
solve();
return 0;
}