日常训练2025-1-19

日常训练2025-1-19

C. Light Switches

rating:1500

https://codeforces.com/problemset/problem/1993/C

思路(Trick)

首先明确一点,当所有的芯片安装完成后,才有可能所有的灯会亮

可以求出芯片安装时刻的最大值max_val

然后就是芯片装好一瞬间就会亮,周期是2k,

现在需要考虑的就是每一个芯片安装时刻到所有装完(max_val)这一段时间是否满足在k内即可

代码

#include <bits/stdc++.h>
typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;
void solve(){
int n, k;
std::cin >> n >> k;
int maxx = 0;
std::vector<int> a(n+1);
for (int i = 1; i <= n; i++) {
std::cin >> a[i];
maxx = std::max(a[i], maxx);
}
// l:最后一个灯安装时,没亮的灯中最晚亮的灯需要走l步。
// r:最后一个灯安装时,亮的灯中最早灭的灯在r步后才会灭
int l = 0, r = k;
for (int i = 1; i <= n; i++){
int x = (maxx - a[i]) % (2 * k);
if (x == k){
l = r + 1;
break;
}
if (x < k){
r = std::min(r, k - x - 1);
}
if (x > k){
l = std::max(l, 2*k - x);
}
}
if (l > r){
std::cout << "-1\n";
}else{
std::cout << maxx + l << '\n';
}
}
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
int t = 1, i;
std::cin >> t;
for (i = 0; i < t; i++){
solve();
}
return 0;
}

C. Mad MAD Sum

rating:1500

https://codeforces.com/problemset/problem/1990/C

思路(Trick)

b数组是前i个数中,中出现次数大于等于2的最大的数。由此我们可以得出经过一次操作以后,得到的新数组一定是单调不减。此时还有可能出现数量为一的数。,所以我们要再进行一次操作,那样这些只出现一次都数都会被左边替代,这样的话得到的数的出现次数都是大于2。往后就是非零部分向右移动。

代码

#include<bits/stdc++.h>
using namespace std ;
#define int long long
int t;
int n;
int sum;
int maxn;
map<int,int> mp ;
signed main()
{
cin>>t ;
while(t--)
{
mp.clear();
cin >> n ;
vector<int> a(n+5);
sum = 0 ;
int maxn = 0 ;
for(int i = 0 ; i < n ; i ++ )
{
cin >> a[i] ;
sum += a[i] ;
mp[a[i]] ++ ;
if(mp[a[i]] >= 2 && a[i] > maxn)
{
maxn = a[i] ;
}
a[i] = maxn ;
}
mp.clear() ;
maxn = 0 ;
for(int i = 0 ; i < n ; i ++ )
{
sum += a[i] ;
mp[a[i]] ++ ;
if(mp[a[i]] >= 2 && a[i] > maxn)
{
maxn = a[i] ;
}
a[i] = maxn ;
}
for(int i = 0 ; i < n ; i ++ )
{
sum += (n - i) * a[i] ;
}
cout << sum << endl ;
}
return 0 ;
}

F. Final Boss

rating:1500

https://codeforces.com/problemset/problem/1985/F

思路(二分)

要理解清楚题意,放了 i 号技能,是 i 号技能会陷入冷却,但是我们还可以用其他技能,角色是不会陷入冷却的。所以如果知道回合数 x 的情况下,我们可以很快的算出我们能用多少个 i 号技能,对于其他任何技能也一样可以很快算出来。所以标准的二分题。答案满足单调性,猜测答案的情况下很容易判断是否可行

评述

原本在想这道题会不会是DP,结果DP有点难,贪心也不现实。看了一眼Jiangly的代码,二分秒了。

代码

#include <bits/stdc++.h>
typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;
void solve(){
int h, n;
std::cin >> h >> n;
std::vector<int> v(n+1), w(n+1);
for (int i = 1; i <= n; i++){
std::cin >> v[i];
}
for (int i = 1; i <= n; i++){
std::cin >> w[i];
}
i64 l = 1, r = 1e11;
while (l < r){
i64 x = (l + r) >> 1;
i64 dmg = 0;
for (int i = 1; i <= n; i++){
dmg += (x + w[i] - 1) / w[i] * v[i];
if (dmg >= h) break;
}
if (dmg >= h){
r = x;
}else{
l = x + 1;
}
}
std::cout << l << '\n';
}
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
int t = 1, i;
std::cin >> t;
for (i = 0; i < t; i++){
solve();
}
return 0;
}

D. Ingenuity-2

rating:1400

https://codeforces.com/problemset/problem/1974/D

思路(思维)

由于初始两人在同一点,那么我们想要保证两人最终在同一点,首先,相反方向可以让一个人走,就可以相互抵消,对于没有抵消的部分,如果是偶数次,那么就可以两人一起走,反之,则无解。所以直接判断相反方向的奇偶性是否相同即可。

注意一些特判,n=2时,必须两条指令相同,因为每人至少走一步。对于 n=4,并且每个方向走出现一次的情况。我们也需要分别让每个人走一对相反的方向即可。

代码

#include <bits/stdc++.h>
typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
#define INF 0x3f3f3f3f
#define MOD 998244353
using i64 = long long;
const int N = 1e5+5;
using namespace std;
void solve() {
int n;
cin >> n;
string s;
cin >> s;
map<char, int> mp;
for (auto c : s) mp[c]++;
if (n == 2 && s[0] != s[1]) return cout << "NO\n", void();
if (n == 4 && mp['N'] && mp['S'] && mp['E'] && mp['W']) {
for (auto c : s) {
if (c == 'N' || c == 'S') cout << "R";
else cout << "H";
}
cout << endl;
return;
}
if ((mp['N'] & 1) != (mp['S'] & 1) || (mp['E'] & 1) != (mp['W'] & 1)) return cout << "NO\n", void();
map<char, int> mp2;
for (auto c : s) {
mp2[c]++;
cout << (mp2[c] & 1 ? "R" : "H");
}
cout << endl;
}
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
int t = 1, i;
std::cin >> t;
for (i = 0; i < t; i++){
solve();
}
return 0;
}

C. Beautiful Triple Pairs

rating:1400

https://codeforces.com/problemset/problem/1974/C

思路

首先可见三元组的个数并不多, 所以我们可以考虑记录下第一个,第二个相等的个数s1,第一个,第三个相等的个数s2, 第二个,第三个相等的个数s3, 然后在记录全部相等的个数s,那么[x, y, z]能够给答案做出的贡献为s1 + s2 + s3 - 3 * s, 由于种情况会统计两次,所以最后除以2

代码

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef tuple<int, int, int> t3;
const int N = 2e5 + 10;
ll a[N];
void solve()
{
int n;
cin >> n;
for (int i = 0; i < n; i ++ )
cin >> a[i];
map<t3, ll> mp;// 存三元组[x, y, z]的个数
map<t3, ll> mp2;//存[x, y, 0], [x, 0, z], [0,, y, z]的个数
for (ll i = 2; i < n; i ++ )
{
mp[{a[i - 2], a[i - 1], a[i]}] ++ ;
mp2[{a[i - 2], a[i - 1], 0}] ++ ;
mp2[{a[i - 2], 0, a[i]}] ++ ;
mp2[{0, a[i - 1], a[i]}] ++ ;
}
ll res = 0;
for (int i = 2; i < n; i ++ )
{
res += mp2[{a[i - 2], a[i - 1], 0}];
res += mp2[{a[i - 2], 0, a[i]}];
res += mp2[{0, a[i - 1], a[i]}];
res -= 3 * mp[{a[i - 2], a[i - 1], a[i]}];
// mp[{a[i - 2], a[i - 1], a[i]}] -- ;
// mp2[{a[i - 2], a[i - 1], 0}] -- ;
// mp2[{a[i - 2], 0, a[i]}] -- ;
// mp2[{0, a[i - 1], a[i]}] -- ;
}
cout << res / 2 << endl;
}
int main()
{
int t;
cin >> t;
while (t -- )
solve();
return 0;
}

本文作者:califeee

本文链接:https://www.cnblogs.com/califeee/p/18679224

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   califeee  阅读(4)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.