A题给我们一个加密后的字符串,让我们还原回去。由题意和样例我们知道我们的加密字符串的格式形同(a-->aba ,c -->cabac),那么我们便可以从前往后遍历一遍,即可得到我们的原始字符串
参考代码:
#include <bits/stdc++.h>
using namespace std;
#define endl '\n';
const int N = 2e5 + 10;
typedef long long ll;
typedef pair<int, int> PII;
void solve()
{
int n;
cin >> n;
string str, ans;
cin >> str;
for (int i = 0; i < n; i++)
{
int j = i;
while (str[++j] != str[i] && j < n);
i = j;
ans += str[i];
}
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
solve();
return 0;
}
B题,二进制咖啡馆
咖啡馆里的物品的价格是2^k(0<=k<n),我们有n元钱,我们可以选择不同的种类去购买,也可以一个都不买,问我们一共有多少种购买方案?2进制,一共有多少种方案(或者说我们用2的次幂可以组成哪些数),这就很明显了。如果我们的钱数大于2^k,那么我们就可以购买价格为(0,1,2,3,4……2^(k)-1)一共有2^k中方案,否则的话,我们的钱数小于最贵的物品,那么我们就可以购买价格为(0,1,2,3……n)一共有n+1中方案数
代码实现:
#include <bits/stdc++.h>
using namespace std;
#define endl '\n';
const int N = 2e5 + 10;
typedef long long ll;
typedef pair<int, int> PII;
void solve()
{
ll n, k;
cin >> n >> k;
if (k > 31)
k = 31;
if ((ll)pow(2, k) > n)
{
cout << n + 1 << endl;
}
else
{
cout << (ll)pow(2, k) << endl;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
solve();
return 0;
}
c题
有一个数学老师,他想去去度假,可是他事比较多,温度高于q的天气他不去,度假最少的天数为k天,问我们他一共可以有多少选择方法可以去度假。
这个题应该算是个模拟,我们先去统计一下可以度假的天数有多少天,如果天数少于我们的最少的天数,那么我们就要输出0。另外的情况我们可以存储每一段连续的天气适宜的天数,因为我们可以直接通过这一段的天数我们就可以直接算出满足要求的方案数,然后全部段的方案一加就可以实现了。
代码实现:
#include <bits/stdc++.h>
using namespace std;
#define endl '\n';
const int N = 2e5 + 10;
typedef long long ll;
typedef pair<int, int> PII;
void solve()
{
ll n, k, q, cnt = 0, minn = +1e9 + 10, ans = 0;
cin >> n >> k >> q;
vector<ll> a(n), b;
for (int i = 0; i < n; i++)
{
cin >> a[i];
minn = min(a[i], minn);
}
if (minn > q)
{
cout << 0 << endl;
return;
}
for (int i = 0; i < n; i++)
{
int j = i;
while (a[i] <= q && i < n)
i++;
b.push_back(i - j);
}
for (auto x : b)
{
if (x == k)
ans++;
if (x > k)
ans += ((1 + (x - k + 1)) * (x - k + 1) / 2);
}
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
solve();
return 0;
}
D题这个题建议多看看看明白他,最近类似的二分题考的挺多的。
问题的大意是,我们有若干的任务(任务有一个pos1),每个任务可以由一个人完成,我们一共有三个人(每个人也有一个pos2),他问我们如何安排这三个人(每个人完成任务的代价是
|pos1-pos2|)如何安排这些人使得我们花费的的代价最小。这题做多了,你就会一眼丁真,二分答案,check函数检查答案是否合格,这里判断是否合格需要O(N),这里我们需要一下优化,比如我们可以将所有的任务分成三段,那么我们的每个人就会负责一段,如果我们的答案无法满足三段就覆盖所有的任务,那么我们的答案就是不满足的的。
代码实现:
#include <bits/stdc++.h>
using namespace std;
#define endl '\n';
const int N = 2e5 + 10;
typedef long long ll;
typedef pair<int, int> PII;
int a[N], n;
bool check(int mid)
{
int now = a[0], cnt = 0;
for (int i = 1; i < n; i++)
{
if (a[i] - now > 2 * mid)
now = a[i], cnt++;
}
if (cnt >= 3)
return false;
else
return true;
}
void solve()
{
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
sort(a, a + n);
int l = 0, r = 1e9;
while (l < r)
{
int mid = (l + r) >> 1;
if (check(mid))
r = mid;
else
l = mid + 1;
}
cout << l << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
solve();
return 0;
}
E题:
大题的意思是给我们两个字符串(由小写字母组成),现在给我们n个问题,问我们在当前时刻的连个字符串是否相等,操作一共有三种,第一种将位置为pos的字符串的字母给挡住t秒(在遮挡没有结束之前我们可以忽略掉这个字母),2交换字符串指定位置上面的字符,3判断两个字符串是否相等。
思路:对与操作一来说,我们可以使用这个字符结束被遮挡的时间作为他,可以被比较的时间,这样我们只需要在这个字符的遮挡消失的时候我们才需要去和他比较,对于操作二,我们需要维护当前字符串不同字符的个数,不过要注意细节。
代码实现:
#include <bits/stdc++.h>
using namespace std;
#define endl '\n';
const int N = 2e5 + 10;
typedef long long ll;
typedef pair<int, int> PII;
unordered_map<int, vector<int>> B;
void solve()
{
string a, b;
cin >> a >> b;
int t, q, dif = 0;
cin >> t >> q;
for (int i = 0; i < a.size(); i++)
if (a[i] != b[i])
dif++;
for (int i = 0; i < q; ++i)
{
int k;
cin >> k;
for (auto x : B[i])
{
if (a[x] != b[x])
dif++;
}
if (k == 1)
{
int pos;
cin >> pos;
pos--;
if (a[pos] != b[pos])
dif--;
B[i + t].push_back(pos);
}
else if (k == 2)
{
int x1, x2, y1, y2;
cin >> x1 >> y1 >> x2 >> y2;
y1--, y2--;
if (x1 == 1 && x2 == 1)
{
if (a[y1] != b[y1])
dif--;
if (a[y2] != b[y2])
dif--;
swap(a[y1], a[y2]);
if (a[y1] != b[y1])
dif++;
if (a[y2] != b[y2])
dif++;
}
else if (x1 == 1 && x2 == 2)
{
if (a[y1] != b[y1])
dif--;
if (a[y2] != b[y2])
dif--;
swap(a[y1], b[y2]);
if (a[y1] != b[y1])
dif++;
if (a[y2] != b[y2])
dif++;
}
else if (x1 == 2 && x2 == 1)
{
if (b[y1] != a[y1])
dif--;
if (a[y2] != b[y2])
dif--;
swap(b[y1], a[y2]);
if (a[y1] != b[y1])
dif++;
if (a[y2] != b[y2])
dif++;
}
else
{
if (a[y1] != b[y1])
dif--;
if (a[y2] != b[y2])
dif--;
swap(b[y1], b[y2]);
if (a[y1] != b[y1])
dif++;
if (a[y2] != b[y2])
dif++;
}
}
else
{
string ans[2] = {"No", "Yes"};
cout << ans[(dif == 0)] << endl;
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--)
solve();
return 0;
}