目录
C. Mark and His Unfinished Essay
题目
A. Mark the Photographer
题意:
给你 2*n个数, 一个数x, 要求把这2n个数分成2组, 保证其中一组每个数都比另一组的数大x, 即.
思路:
把这2n个数sort下, 截取成两段, 逐个对应判断是否存在即可, 有点贪心思想.
code:
/**
* author: CurleyD
* created: 07.15.2022 21:35:34
**/
#include <bits/stdc++.h>
#define endl '\n'
#define IO ios::sync_with_stdio(false); cin.tie(nullptr);
using namespace std;
typedef long long LL;
//#define LOCAL
//#define int LL
//head
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
int T, n, m, x;
int a[N];
void solve() {
cin >> n >> x;
for (int i = 1; i <= n * 2; i++)
cin >> a[i];
sort(a+1,a+1+2*n);
for (int i = 1; i <= n; i++) {
if (a[i+n] - x >= a[i]) {
continue;
}
else {
cout << "NO\n";
return;
}
}
cout<<"YES\n";
}
signed main() {
IO;
#ifdef LOCAL
freopen("out.txt","w",stdout);
#endif
cin >> T;
while(T--) {solve();}
return 0;
}
B. Mark the Dust Sweeper
题意:
题目给的题意不明确, 大概意思就是给你个n个正数, 对于 1~n 你可以任选 i, j在这范围之内
进行 ai = ai - 1, aj = aj + 1, (需要保证为正), 问你最少多少次使得 1~n-1的数全为0? 描述的可能不太清晰...
思路:
根据下面的提示来看似乎不能一直选j=n???
观察样例 + 猜想 + 结合实际吸尘器不能跳着吸只能顺着推可知, ans = (1~n-1的ai) + (1~n-1相邻的正数相差的0的数量即间隔数);
不知道怎么证明???
code:
/**
* author: CurleyD
* created: 07.15.2022 21:57:42
**/
#include <bits/stdc++.h>
#define endl '\n'
#define IO ios::sync_with_stdio(false); cin.tie(nullptr);
using namespace std;
typedef long long LL;
//#define LOCAL
//#define int LL
//head
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 10;
int T, n, m;
int a[N];
void solve() {
cin >> n;
LL res = 0;
LL cnt = 0;
for (int i = 1; i <= n; i++)
cin >> a[i];
bool f = 0;
for (int i = 1; i <= n - 1; i++) {
if (a[i] != 0) {
f = 1;
res = res + a[i] + cnt;
cnt = 0;
}
if (a[i] == 0 && f) {
cnt ++;
}
}
res += cnt;
cout << res << endl;
}
signed main() {
IO;
#ifdef LOCAL
freopen("out.txt","w",stdout);
#endif
cin >> T;
while(T--) {solve();}
return 0;
}
C. Mark and His Unfinished Essay
题意:
给你个长度n的字符串, 每次可截取l, r 放在字符串的末尾使得字符串的长度跟着增长, 进行完上述操作给你k个询问, 每个询问给你个位置, 输出增长完的字符串的对应字符是什么?
思路:
l, r 都是1e18显然模拟会超时, 开始一直想着hash来做, 但是我不会
我的做法可能会fst...但pretest过了
通过他最大每次可能给30次修改, 想到可以溯源每个pos映射在原来s串的位置
具体解释下的话如下:
一个样例:n=4,m=3,k=1,s="mark"
4 3 1
mark
1 4
5 7
3 8
10
三次修改, 一次查询
我们用newl表示新增区间l, newr同理, len表示新增区间的长度.
markmark l = 1, r = 4, newl = 5, newr = 8, len = 4
markmarkmar l = 5, r = 7, newl = 9, newr = 11, len = 3
markmarkrkmark l = 3, r = 8, newl = 12, newr = 17, len = 6
对于pos = 10, 它是由l=5,r=7区间变成的, 则pos相当于其中的 x = 6!
因此我们可以把pos设置成pos = 6!!!
同理pos=6 -> pos=newl - l + pos!!!
因此我们的过程大致为:
1)读入s,n,m,k, 设置SZ=s.size() (以后要更新会增长)
2)读入l, r 对于每组l,r, 记录其新老l,r到结构体数组p中 即len, 更新SZ
3)sort下p, 方便之后找, 当然不sort估计也行
4)查询过程, 对于每个pos, 进行溯源, 直到pos 在 1~n之间为止!
得解
要是没有fst那证明这个做法可行的, 但感觉应该是对的.
code:
/**
* author: CurleyD
* created: 07.15.2022 22:08:18
**/
#include <bits/stdc++.h>
#define endl '\n'
#define IO ios::sync_with_stdio(false); cin.tie(nullptr);
using namespace std;
typedef long long LL;
//#define LOCAL
//#define int LL
//head
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
int T, n, m, k;
LL l, r, pos;
struct node{
LL l, r, len;
LL x, y;
}p[55];
bool cmp(node a, node b) {
return a.l < b.l;
}
void solve() {
string s;
cin >> n >> m >> k;
cin >> s;
LL SZ = s.size();
s.insert(s.begin(),'#');
for (int i = 1; i <= m; i++) {
cin >> l >> r;
LL len = r - l + 1;
//老区间
p[i].x = l;
p[i].y = r;
//新区间
p[i].l = SZ + 1;
p[i].r = SZ + len;
p[i].len = len;
SZ += len;
//cout<<p[i].l << " " << p[i].r << endl;
}
sort(p + 1, p + 1 + m, cmp);
for (int q = 1; q <= k; q++) {
cin >> pos;
while (pos > n) {
for (int i = 1; i <= m; i++) {
if (p[i].l <= pos && p[i].r >= pos) {
pos = p[i].x + pos - p[i].l;
// cout << pos << endl;
break;
}
}
}
cout<<s[pos]<<endl;
}
}
signed main() {
IO;
#ifdef LOCAL
freopen("out.txt","w",stdout);
#endif
cin >> T;
while(T--) {solve();}
return 0;
}
/*
5->7
9->11 10 - 9 + 5 -> 6
*/
总结:
1)简单题思路形成慢,
2)过于依赖翻译
3)有时候写一半发现漏掉条件/读了假题 ->这次的B
4)会在细节出问题, ->这次的C, 结构体里忘记开LL, len忘开LL导致出现负数溢出, 血亏.
毕竟是菜狗, 第一次赛时出c已经挺高兴了, D似乎是个dp? 看了下tourist的不是dp...
update:
开测了QAQ
没FST, 好耶LOL