codeforces比赛(4):codeforces hello_2024
A、Wallet Exchange
跳转原题点击此:A题地址
1、题目大意
经典贪心:A和B玩游戏,两人依次进行以下两个操作(注意这两个操作是依次进行,而不是选择操作!!!)是:1、交换钱包或保留钱包;2、从玩家当前钱包中取出1枚硬币(注意不能为0)。
A先走,并且当某位玩家无法做出有效举动时,另一位玩家获胜。(即两位玩家钱包都为0)。
2、题目解析
因为两位玩家都是选择最佳操作,所以最佳操作为将钱包里面的硬币先搞到0枚,这样就能通过交换钱包先手减去对方钱包里面的硬币。
又因为A是先手操作,所以当钱包总数为奇数时,A为必胜态;钱包总数为偶数,B为必胜态。
因为偶数时,两人能进行的操作为1、交换钱包减去1;2、保留钱包减去1。所以无论哪种硬币总数都减1,所以当偶数时,A最后执行只剩零枚,所以B赢;奇数同理。
小技巧:这种简单的博弈论,直接面对案例输出即可,比如这里看案例发现a+b为偶数B赢,奇数A赢,直接输出即可。
3、具体代码
#include<bits/stdc++.h>
using namespace std;
int T;
int a, b;
void solve()
{
cin >> a >> b;
if((a + b) % 2 == 0)
cout << "Bob\n";
else
cout << "Alice\n";
}
int main()
{
cin >> T;
while (T--)
{
solve();
}
return 0;
}
B、Plus-Minus Split
跳转原题点击此:B题地址
1、题目大意
给定一个字符串,包含'+'和'-'两种字符,意思为+1和-1。让我们对该字符串划分为若干个依次连接的子字符串,要求划分的每个子字符串相加后的绝对值 的 全部总和最小。
2、题目解析
由于划分的字符串是依次连接的,所以我们划分的依据是让每个子串里面的+和-尽可能一样,所以我们只需要统计+和-的个数,然后求出其差值即可。
3、具体代码
#include<bits/stdc++.h>
using namespace std;
int T;
int n;
void solve()
{
string s;
int a = 0, b = 0;
cin >> n >> s;
for(auto t : s)
{
if(t == '-')
a++;
else
b++;
}
cout << abs(a - b) << endl;
}
int main()
{
cin >> T;
while (T--)
{
solve();
}
return 0;
}
C、Grouping Increases
跳转原题点击此:C题地址
1、题目大意
将给定的数组划分为s和t两个子数组,并且允许出现空子数组。要求划分后的s和t其最小代价之和最小。
1、划分依据:如[3、5、2、7、1]可以划分为[3、7、1]和[5、2],只要新的子数组满足原字符串的顺序即可。
2、代价:如[3、5、2、7、1]的代价就是2,即5>3 和 7>2。换句话说就是求出子数组中出现递增的次数。
2、题目解析
即可以生成两个栈,将元素依次存入到两个栈中;
1、按照非递增的规律存入到符合条件地栈中,如果两个栈都满足,那就选择栈顶小的那个栈里面。这是因为保持栈的最大灵活性。如2选择放入5和3中,如果选择5,那么之后如果出现4就无法放入。所以选择较小栈顶的栈可以扩大栈的灵活性;
2、如果两个栈都不符合条件,说明存在
如两个栈顶元素为6、7,后面两个元素为10、7。如果10放入7后面,那么就会多一个代价,而放入6后面则不会。所以选择小的栈顶是为了更大化灵活性。
3、具体代码
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int INF = 1e9 + 10;
int T;
int n;
int f[N];
void solve()
{
cin >> n;
int ans = 0;
for(int i = 1; i <= n; i++)
cin >> f[i];
stack<int> a, b;
a.push(INF), b.push(INF); // 初始化
for(int i = 1; i <= n; i++)
{
int x = a.top();
int y = b.top();
// 分类讨论,将当前数存放到t还是s中
// 1、当该数都比t和s的栈顶<=
if(f[i] <= x && f[i] <= y)
{
// 放入进行栈顶小的那个栈里面
if(x < y)
a.push(f[i]);
else
b.push(f[i]);
}
// 2、如果a栈小,放入a
else if(f[i] <= x && f[i] > y)
a.push(f[i]);
// 3、如果b栈小,放入b
else if(f[i] > x && f[i] <= y)
b.push(f[i]);
// 4、如果都比两个栈顶大
else if(f[i] > x && f[i] > y)
{
// 放入栈顶小的那个栈中
if(x > y)
b.push(f[i]);
else
a.push(f[i]);
// 由于出现了递增,那么答案代价就加一
ans++;
}
}
cout << ans << endl;
}
int main()
{
cin >> T;
while (T--)
{
solve();
}
return 0;
}
未完待续
后序题目对我来说实在是太难了,得等很久很久才能补掉。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人