A. Equal or Not Equal
题目描述
你有 n 个正整数 a1,a2,…,an 排列成一个圆圈。对于每对相邻的数字(a1 和 a2,a2 和 a3,…,an−1 和 an,以及 an 和 a1),您写下:这对数字中的数字是否相等。
不幸的是,您丢失了一张带有数组 a 的纸。此外,您担心即使有关相邻元素相等的信息也可能不一致。所以,您想知道:是否有任何数组 a 与您所掌握的关于对应对的相等或不相等的信息一致?
输入
第一行包含一个整数 t (1≤t≤1000)——测试用例的数量。接下来是 t 个案例。
每个测试用例的第一行也是唯一的一行包含一个由字符 E 和/或 N 组成的非空字符串 s。 s 的长度等于数组 n 的大小并且 2≤n≤50。对于从 1 到 n 的每个 i:
如果 si= E 则 ai 等于 ai+1(对于 i=n,an=a1);
如果 si= N,则 ai 不等于 ai+1(对于 i=n,an≠a1)。
输出
对于每个测试用例,如果可以选择与您知道的 s 中的信息一致的数组 a,则打印 YES。否则,打印 NO。
可以证明,如果存在某个数组a,则存在一个由小于或等于109的正整数组成的数组a。
code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
const int maxn=1e6+5;
void solve(){
string s;
cin >> s;
int n = s.size();
int cnt = 0;
//错误理解
// if(s[n-2]=='N')
// cout << "YES\n";
// else if(s[n-2]=='E'){
// for (int i = 0; i < n - 2;i++){
// if(s[i]=='N')
// cnt++;
// }
// if(cnt%2==0){
// if(s[n-1]=='N')
// cout << "NO\n";
// else
// cout << "YES\n";
// }
// else
// cout << "NO\n";
// // if(s[n-1]=='E')
// // cout << "NO\n";
// // else
// // cout << "YES\n";
// }
for (int i = 0; i < n;i++){
if(s[i]=='N')
cnt++;
}
if(cnt==1)
cout << "NO\n";
else
cout << "YES\n";
}
int main(){
ios::sync_with_stdio(0);
int t;
cin >> t ;
while(t--){
solve();
}
return 0;
}
B. Triangles on a Rectangle
题目描述
在平面上绘制一个矩形,其对角位于 (0,0) 和 (w,h) 且边与轴平行。
给定一个格点列表,每个点都位于矩形的一侧,但不在其角上。此外,矩形的每一边至少有两个点。
你的任务是以这样的方式选择三个点:
它们中的两个正好属于矩形的同一边;
由它们形成的三角形的面积是最大的。
打印这个三角形的两倍面积。可以证明,任何由格点组成的三角形的两倍面积总是一个整数。
输入
第一行包含一个整数 t (1≤t≤104)——测试用例的数量。
每个测试用例的第一行包含两个整数 w 和 h (3≤w,h≤106)——矩形角的坐标。
接下来的两行包含对两个水平边上的点的描述。首先,一个整数 k (2≤k≤2⋅105)——点数。然后,k 个整数 x1<x2<⋯<xk (0<xi<w) — 按升序排列的点的 x 坐标。第一行的 y 坐标为 0,第二行的 y 坐标为 h。
接下来的两行包含对两个垂直边上的点的描述。首先,一个整数 k (2≤k≤2⋅105)——点数。然后,k 个整数 y1<y2<⋯<yk (0<yi<h)——点的 y 坐标按升序排列。第一行的 x 坐标为 0,第二行的 x 坐标为 w。
所有测试用例中所有边的总点数不超过 2⋅105。
输出
对于每个测试用例,打印一个整数——由三个点形成的三角形的最大面积的两倍,其中三个点恰好属于同一边。
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
const int maxn=1e6+5;
void solve(){
int x, y;
cin >> x >> y;
ll maxx = 0;
ll maxy = 0;
for (int i = 0; i < 2;i++){
int n;
cin>>n;
ll a,b;
ll x;
for (int j = 0; j < n; j++){
cin>>x;
if(j==0)a=x;
if(j==n-1)b=x ;
}
maxx = max(maxx, (b-a));
}
for (int i = 0; i < 2;i++){
int n;
cin>>n;
ll a,b;
ll x;
for (int j = 0; j < n; j++){
cin>>x;
if(j==0)a=x;
if(j==n-1)b=x ;
}
maxy = max(maxy, (b-a));
}
ll num = max(maxx * y, maxy * x);
cout << num << endl;
}
int main(){
ios::sync_with_stdio(0);
int t;
cin >> t ;
while(t--){
solve();
}
return 0;
}
C. BA-String
题目描述
给定一个整数 k 和一个仅由字符“a”(小写拉丁字母)和“*”(星号)组成的字符串 s。
每个星号应替换为几个(从 0 到 k 包括在内)小写拉丁字母“b”。不同的星号可以替换为不同数量的字母“b”。
替换的结果称为 BA 字符串。
如果两个字符串 a 和 b 具有不同的长度或存在这样的位置 i 使得 ai≠bi,则它们是不同的。
当且仅当以下条件之一成立时,字符串 a 在字典序上小于字符串 b:
- a是b的前缀,但a≠b;
- 在 a 和 b 不同的第一个位置,字符串 a 有一个字母在字母表中比 b 中的相应字母出现得更早。
现在考虑所有不同的 BA 字符串并找到其中第 x 个字典序最小的字符串。
输入
第一行包含一个整数 t (1≤t≤2000)——测试用例的数量。
每个测试用例的第一行包含三个整数 n 、 k n、k n、k 和 x ( 1 ≤ n ≤ 2000 ; 0 ≤ k ≤ 2000 ; 1 ≤ x ≤ 1 0 18 ) x(1≤n≤2000;0≤k≤2000;1≤x≤10^{18}) x(1≤n≤2000;0≤k≤2000;1≤x≤1018)。 n 是字符串 s 的长度。
每个测试用例的第二行是一个字符串 s。它由 n 个字符组成,每个字符都是“a”(小写拉丁字母)或“*”(星号)。
所有测试用例的 n 总和不超过 2000。对于每个测试用例,x 不超过不同 BA 字符串的总数。字符串 s 至少包含一个字符 ‘a’。
输出
对于每个测试用例,打印一个字符串,只包含字符 ‘b’ 和 ‘a’(小写拉丁字母)——第 x 个字典序最小的 BA 字符串。
code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
const int maxn = 1e6 + 5;
void solve()
{
ll n, k, x;
cin >> n >> k >> x;
string s;
cin >> s;
if (x == 1 || k == 0)
{
string ans = "";
for (int i = 0; i < n;i++)
{
if (s[i] == 'a')
{
ans.push_back('a');
}
}
cout << ans << endl;
return;
}
vector<int> v;
for (int i = n - 1; i >= 0; i--)
{
if (s[i] == '*')
{
if (i < (n - 1) && s[i + 1] == '*')
{
v.back() += k;
}
else
{
v.push_back(k + 1);
}
}
}
int m = v.size();
ll s1 = 1;
vector<int> cnt(m, 0);
int i = 0;
for (; i < m; i++)
{
double dx = v[i];
double nn = (x / dx);
if (nn <= s1)
{
for (int j = i; j >= 0; j--)
{
if (j != i)
s1 = s1 / v[j];
cnt[m - j - 1] = (x - 1) / s1;
x = (x - 1) % s1 + 1;
}
break;
}
s1 = s1 * v[i];
}
int inn = m - 1;
char prev = 'a';
string z = "";
for (int i = n - 1; i >= 0; i--)
{
if (s[i] == '*' && prev == '*')
{
s.erase(s.begin() + i);
continue;
}
else if (s[i] == '*')
{
z = "";
while (cnt[inn]--)
{
z.push_back('b');
}
s.erase(s.begin() + i);
s.insert(i, z);
inn--;
prev = '*';
}
else
{
prev = 'a';
}
}
cout << s << endl;
}
int main()
{
ios::sync_with_stdio(0);
int t;
cin >> t;
while (t--)
{
solve();
}
return 0;
}
D. Exact Change
题目描述
一天,一大早,你决定在附近的商店给自己买一袋薯条。这家商店有n种不同口味的薯条。一袋第 i 种口味的价格为 a i a_i ai burles。
这家商店的一些口味可能会用完,所以你到了那里再决定买哪一种。但是这个计划有两个主要缺陷:
你只有 1、2 和 3 个 burles 的硬币;
由于现在是早上,商店会要求您支付确切的零钱,即。 e.如果你选择第 i 种口味,你将不得不支付完全 a i a_i ai burles。
硬币很重,因此您希望总共拿走尽可能少的硬币。这就是为什么您想知道:您应该随身携带的最少硬币总数是多少,以便您可以零钱购买一袋任何口味的薯片?
输入
第一行包含一个整数 t (1≤t≤1000)——测试用例的数量。
每个测试用例的第一行包含单个整数 n (1≤n≤100)——商店中口味的数量。
每个测试用例的第二行包含 n 个整数 a 1 , a 2 , … , a n ( 1 ≤ a i ≤ 1 0 9 ) a_1,a_2,…,a_n (1≤a_i≤10^9) a1,a2,…,an(1≤ai≤109)——每种口味一袋的成本。
输出
对于每个测试用例,打印一个整数——购买一袋任何口味的零钱所需的最少硬币数。
code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
const int maxn=1e6+5;
int a[maxn], b[maxn];
int cnt[3];
void solve(){
int n;
cin >> n;
cnt[0] = cnt[1] = cnt[2] = 0;
int res = 0, max_a = 0, flag_1 = 0, flag_max = 0;;
for(int i = 1; i <= n; i ++) {
cin >> a[i];
cnt[a[i] % 3] ++;
res = max(res, a[i] / 3);
max_a = max(max_a, a[i]);
if(a[i] == 1) flag_1 = 1;
}
for(int i = 1; i <= n; i ++) {
if(max_a - 1 == a[i]) {
flag_max = 1;
}
}
if(cnt[1] == cnt[2] && cnt[1] == 0) {
cout << res << '\n';
}
else if(cnt[2] == 0 || cnt[1] == 0) {
cout << res + 1 << '\n';
}
else if(max_a % 3 == 0) {
cout << res + 1 << '\n';
}
else if(max_a % 3 == 1 && !flag_1 && !flag_max) {
cout << res + 1 << '\n';
}
else {
cout << res + 2 << '\n';
}
}
int main(){
ios::sync_with_stdio(0);
int t;
cin >> t ;
while(t--){
solve();
}
return 0;
}
E. Replace the Numbers
题目描述
您有一个整数数组(最初为空)。
您必须执行 q 查询。 每个查询属于以下两种类型之一:
"1 x"
— 将元素 x 添加到数组的末尾;
"2 x y"
— 用 y 替换数组中所有出现的 x。
执行所有查询后找到结果数组。
输入
第一行包含一个整数 q ( 1 ≤ q ≤ 5 ⋅ 1 0 5 ) q (1≤q≤5⋅10^5) q(1≤q≤5⋅105)——查询的数量。
接下来的 q 行包含查询(每行一个)。 每个查询属于以下两种类型之一:
" 1 x " ( 1 ≤ x ≤ 5 ⋅ 1 0 5 ) "1 x" (1≤x≤5⋅10^5) "1x"(1≤x≤5⋅105);
" 2 x y " ( 1 ≤ x , y ≤ 5 ⋅ 1 0 5 ) "2 x y" (1≤x,y≤5⋅10^5) "2xy"(1≤x,y≤5⋅105)。
保证至少有一个第一种类型的查询。
输出
在一行中,打印 k 个整数——执行所有查询后的结果数组,其中 k 是第一种类型的查询数。
code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
const int maxn = 1e6 + 5;
int q;
map<int, int> m;
vector<pair<int, int>> qs;
void solve()
{
cin >> q;
for (int i = 0; i < q; i++)
{
int t;
cin >> t;
qs.push_back({
-1, -1});
if (t == 1)
cin >> qs.back().second;
else
cin >> qs.back().first >> qs.back().second;
}
vector<int> ans;
for (int i = q - 1; i >= 0; i--)
{
if (m[qs[i].second] == 0)
m[qs[i].second] = qs[i].second;
if (qs[i].first == -1)
ans.push_back(m[qs[i].second]);
else
m[qs[i].first] = m[qs[i].second];
}
reverse(ans.begin(),ans.end());
for (auto x : ans)
cout << x << ' ';
cout << '\n';
}
int main()
{
ios::sync_with_stdio(0);
int t;
t=1;
while (t--)
{
solve();
}
return 0;
}