A - Deletions of Two Adjacent Letters
题意
每次选择任意两个相邻的两个字符删除,问最后是否能得到给定的字符
题解
我们发现,因为每次都是选择两个相邻的字符,那么我们想要保留下来的答案的两端绝对不能出现奇数长度,也就是说,这个字符必须在对应下标的奇数位上(下标从1开始)
那么我们只需要看看原串的奇数位中有没有出现我们想要的字符就可以了
Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#include <unordered_map>
#define ll long long
#define ull unsigned long long
#define re return
#define pb push_back
#define Endl "\n"
#define endl "\n"
#define x first
#define y second
#define all(x) (x).begin(),(x).end()
using namespace std;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
const int M = 1e5 + 10;
const int mod = 1000000007;
const int INF = 0x3f3f3f3f;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int T;
string s;
char c;
void solve(){
cin >> s;
cin >> c;
for (int i = 0; i < s.size(); i += 2){
// cout << s[i] << ' ';
if(s[i] == c){
cout << "YES" << Endl;
re;
}
}
cout << "NO" << Endl;
}
int main(){
// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
T = 1;
cin >> T;
while(T--){
solve();
}
}
B - DIV + MOD
题意
给定l和r,问在这个区间中选数x,使得 f a ( x ) = ⌊ x a ⌋ + x m o d a f_a(x)=\left\lfloor\frac{x}{a}\right\rfloor + x \bmod a fa(x)=⌊ax⌋+xmoda最大的最大值是多少
题解
我们知道,x%a的最大值就是a-1,而前面的答案在取的时候是慢慢的递增的,如果使x%a最大,也就是取得在r以内能被a整除的最大值减一,即 r / a ∗ a − 1 r/a*a-1 r/a∗a−1,而如果这个数不在这个lr区间内,那么说明我们当前的区间在 x / a x/a x/a的情况下都是相等的,所以 f a ( r ) f_a(r) fa(r)也是一种可能的最大值
因为我们不能判断两者的最大值在某个数的情况下最大,所以我们可以直接取max
Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#include <unordered_map>
#define ll long long
#define ull unsigned long long
#define re return
#define pb push_back
#define Endl "\n"
#define endl "\n"
#define x first
#define y second
#define all(x) (x).begin(),(x).end()
using namespace std;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
const int M = 1e5 + 10;
const int mod = 1000000007;
const int INF = 0x3f3f3f3f;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int T;
int l, r, a;
void solve(){
cin >> l >> r >> a;
int x = r / a * a - 1;
int res1 = r / a + r % a;
int res2 = 0;
if(x >= l)
res2 = x / a + x % a;
cout << max(res1, res2) << endl;
}
int main(){
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
T = 1;
cin >> T;
while(T--){
solve();
}
}
C - Weight of the System of Nested Segments
题意
给定m个点,给定每个点的权值和在数轴上的坐标,嵌套的构成系统,每一个连线都要严格的在外面的圈内,问怎么构造n个系统,使得选取的2*n个点的权值最小
题解
和最小肯定是取前2n个最小值来构造答案
我们按权值排序,选取其中2n个点,然后按照这些2n个点的坐标来排序即可,然后俩俩选取
(这里是求加和的最小值,而不是比如问两个端点乘积后加和的最小值等对计算顺序有影响的操作,所以哪几个构成系统顺序是无所谓的,只要是那几个点就行,我就是因为这里卡主了不敢动手
Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#include <unordered_map>
#define ll long long
#define ull unsigned long long
#define re return
#define pb push_back
#define Endl "\n"
#define endl "\n"
#define x first
#define y second
#define all(x) (x).begin(),(x).end()
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5 + 10;
const int M = 1e5 + 10;
const int mod = 1000000007;
const int INF = 0x3f3f3f3f;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int T;
int n, m;
struct nope
{
int x, w, id;
} a[N];
void solve(){
cin >> n >> m;
for (int i = 1; i <= m; i++){
cin >> a[i].x >> a[i].w;
a[i].id = i;
}
sort(a + 1, a + 1 + m, [](nope a, nope b)
{ return a.w < b.w; });
int summ = 0;
for (int i = 1; i <= 2 * n; i++){
summ += a[i].w;
}
cout << summ << endl;
sort(a + 1, a + 1 + 2 * n, [](nope a, nope b)
{ return a.x < b.x; });
for (int i = 1, j = 2 * n; i <= n; i++, j--){
cout << a[i].id << ' ' << a[j].id << endl;
}
cout << endl;
}
int main(){
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
T = 1;
cin >> T;
while(T--){
solve();
}
}
D - Twist the Permutation
题意
从前往后选择当前的数放到最前面,然后这个数前面的其他的数后移
问对于每一位需要操作几次才能使得1,2,3,...,n
变为给定的数列
题解
如果你模拟过一遍样例你就会发现
根本没有头绪
有句话说的好,正难则反
我们发现,当前位操作之后不会影响后面的数变化,那么我们假设我们的数列一开始就是原数列,然后变为1,2,3,..,n
,那么我们不如把每一位都让他是答案,从后往前来进行操作,那么我们就模拟这个过程就好了
Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#include <unordered_map>
#define ll long long
#define ull unsigned long long
#define re return
#define pb push_back
#define Endl "\n"
#define endl "\n"
#define x first
#define y second
#define all(x) (x).begin(),(x).end()
using namespace std;
typedef pair<int, int> PII;
const int N = 1e5 + 10;
const int M = 1e5 + 10;
const int mod = 1000000007;
const int INF = 0x3f3f3f3f;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int T;
int n;
int b[N];
int tmp[N];
void solve(){
cin >> n;
// vector<int> v;
for (int i = 1; i <= n; i++){
cin >> b[i];
// v.pb(b[i]);
}
vector<int> res;
for (int i = n; i >= 1; i --){
int cnt = 0;
int j;
for (j = 1; j <= i; j++){
if(b[j] == i){
break;
}
}
res.pb(j % i);
// cout << i - j << ' ' << j << Endl;
for (int k = j + 1; k <= i; k++){
tmp[++cnt] = b[k];
}
for (int k = 1; k < j; k++){
tmp[++cnt] = b[k];
}
memcpy(b, tmp, sizeof(b));
}
reverse(all(res));
for(auto i : res){
cout << i << ' ';
}
cout << endl;
}
int main(){
// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
T = 1;
cin >> T;
while(T--){
solve();
}
}
G是一个次短路板题,改一下进阶指南的代码就能过