2022杭电第二场
B C++ to Python
题目大意
删除掉字符串里面多余的东西,然后输出。
数据范围
\(1 \leq T \leq 100 ,\ 0 \leq S \leq 1000\)
思路
签到题,把不需要的直接不输出就可以了
$Code$
#include<bits/stdc++.h>
#define IO std::ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
using namespace std;
void slove()
{
string s;
cin >> s;
string ans;
for (int i = 0; s[i]; i++)
{
if (s[i] == '(' or s[i] == ')' or (s[i] <= '9' and s[i] >= '0') or s[i] == '-' or s[i] == ',')ans += s[i];
}
cout << ans << endl;
}
int main()
{
IO
int _T;
cin >> _T;
while (_T--)
{
slove();
}
return 0;
}
C Copy
题目大意
给你一个数组,有两个操作,操作\(1\)是给你一个区间\([l,r]\),你需要把这个区间复制之后,插入到\(r\)后面,操作\(2\)是给一个位置\(x\)你需要把这个位置上面的数\(a[x]\)异或起来,求异或和,最后输出。
数据范围
\(1 \leq T \leq 10,1 \leq n,q \leq 10^{5},1 \leq a_i \leq 10^{9},\sum n \leq 10^5,\sum q \leq 10^{5},1 \leq x_i,l_i,r_i \leq n\)
思路
第一种方法暴力能水过去
标程是使用\(bitset\)优化
因为是异或,异或的特性可以使用\(bitset\)很好的优化
$Code$
#include<bits/stdc++.h>
#define IO std::ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
using namespace std;
int n, q, ans;
vector<int> vec;
void slove()
{
cin >> n >> q;
vec.clear();
for (int i = 1; i <= n; i++)
{
int x;
cin >> x;
vec.push_back(x);
}
int ans = 0;
while (q--)
{
int op;
int x, y;
cin >> op;
if (op == 1)
{
cin >> x >> y;
--x;
vec.insert(vec.begin() + y, vec.begin() + x, vec.begin() + y);
vec.resize(n);
}
else
{
cin >> x;
ans ^= vec[x - 1];
}
}
cout << ans << '\n';
}
int main()
{
IO
int _T;
cin >> _T;
while (_T--)
{
slove();
}
return 0;
}
$std\_Code$
/**
*
* @file Copy
* @link http://acm.hdu.edu.cn/showproblem.php?pid=7152
* @author: liyajun
* @date: 2022-07-27 22:22:32
*
**/
#include<bits/stdc++.h>
#define IO std::ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
using namespace std;
const int N = 1e5 + 10;
int n, m, a[N];
int que[N][3];
bitset<N> f, low, high;
void slove()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
for (int i = 1; i <= m; i++)
{
cin >> que[i][0];
if (que[i][0] == 1)
{
cin >> que[i][1] >> que[i][2];
}
else
{
cin >> que[i][1];
}
}
f.reset();
for (int i = m; i >= 1; i--)
{
if (que[i][0] == 1)
{
int l = que[i][1], r = que[i][2];
low = f & (~bitset<N>(0) >> (N - r - 1));
high = f & (~bitset<N>(0) << (r + 1));
f = low ^ (high >> (r - l + 1));
}
else
{
int x = que[i][1];
f[x] = !f[x];
}
}
int ans = 0;
for (int i = 1; i <= n; i++)
{
if (f[i])ans ^= a[i];
}
cout << ans << '\n';
}
int main()
{
IO
int _T = 1;
cin >> _T;
while (_T--)
{
slove();
}
return (0 - 0);
}
G Snatch Groceries
题目大意
给你时间段\([T_{begin},T_{end}]\),当时间重叠了就是截止时间,问最多有多少个时间段。
数据范围
\(0\leq T \leq 10,1 \leq n \leq 10^{5},0 \leq T_{begin} < T_{end} \leq 10^{9}\)
思路
模拟(像是活动安排类的变形),当前后有重叠了就直接退出,数据需要排序。(题目有点阅读理解了)
$Code$
struct Node
{
int l, r;
bool operator < (Node &a)
{
return l == a.l ? r < a.r : l < a.l;
}
} node[N];
void slove()
{
cin >> n;
lp(i, 1, n)cin >> node[i].l >> node[i].r;
sort(node + 1, node + 1 + n);
int ed = node[1].r;
int ans = 0;
bool f = 1;
lp(i, 2, n)
{
if (ed < node[i].l)
{
if (f)ans++;
ed = node[i].r;
f = 1;
}
else
{
f = 0;
break;
}
}
if (f) ans++;
cout << ans << endl;
}
I ShuanQ
题目大意
私钥\(P\),公钥\(Q\),\(P,Q\)满足 \(P\times Q \equiv1 \pmod M\)
有两个式子
已知\(P,Q,ed\)求解出来\(rd\)
数据范围
\(T \leq 20,1 < P,Q,ed \leq 2\times 10^6\),保证\(P,Q,ed < M\)。
思路
\(P\times Q \equiv 1 \mod M\)能推出 \(P\times Q - 1 = k\times M,1\leq k\),其中\(M\)是\(kM\)比\(P,Q\)大的质因子,并且是唯一的,若是有多个满足要求的质因子的话\(M_1\times M_2\times \cdots \times M_n > P \times Q\)与上面矛盾了
队友赛时代码
$Code$
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
typedef long long ll;
bool isprime(ll n)
{
if (n <= 3)
{
return n > 1;
}
if (n % 6 != 1 && n % 6 != 5)
{
return false;
}
for (ll i = 5; i <= sqrt(n); i += 6)
{
if (n % i == 0 || n % (i + 2) == 0)
{
return false;
}
}
return true;
}
ll prime(ll x)
{
if (isprime(x))
{
return x;
}
for (ll i = 2; i <= sqrt(x); i++)
{
if (x % i == 0)
{
if (isprime(x / i)) return x / i;
}
}
return -1;
}
int main()
{
int T;
cin >> T;
while (T--)
{
int p, q, e;
cin >> p >> q >> e;
ll res = (ll)p * q - 1;
ll M = prime(res);
if (M == -1)
{
cout << "shuanQ" << endl;
}
else
{
cout << (e % M * q % M) % M << endl;
}
}
return 0;
}
L Luxury cruise ship
题目大意
每天可以获取\(7,31,365\)个金币,给你一个价格,然你求最少多少天 恰好 能够买的起
数据范围
\(T \leq 1000, 1\leq N \leq 10^{18}\)
思路
贪心加上一点数论
求取\(7,31,365\)的公倍数,也就是先把比较大的部分给处理,剩下的交给预先处理好的数据
队友赛时的代码,先预处理小范围的数据,之后就可以直接查表了。
$Code$
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100000
typedef unsigned long long ull;
int f[79210];
int main()
{
int T;
for (int i = 0; i < 79210; i++)
{
f[i] = MAXN;
}
f[7] = 1;
f[31] = 1;
f[365] = 1;
f[14] = 2;
f[21] = 3;
f[28] = 4;
for (int i = 14; i <= 79205; i++)
{
if (f[i] != MAXN)
{
continue;
}
if (i > 31)
{
if (f[i - 31] != MAXN || f[i - 7] != MAXN)
{
f[i] = min({f[i], f[i - 31], f[i - 7]}) + 1;
}
}
if (i > 365)
{
if (f[i - 31] != MAXN || f[i - 7] != MAXN || f[i - 365] != MAXN)
{
f[i] = min({f[i], f[i - 7], f[i - 31], f[i - 365]}) + 1;
}
}
}
cin >> T;
while (T--)
{
ull sum;
ull res = 0;
cin >> sum;
res += (sum / 79205 * 217);
sum %= 79205;
if (f[sum] == MAXN)
{
cout << -1 << endl;
}
else
{
res += f[sum];
cout << res << endl;
}
}
return 0;
}
除了模拟 ,还有两种办法求解预处理数据
首先就是完全背包,很好理解,就是,三种物品无限取,求取最少的使用量
$Code$
void init1()
{
memset(f, 0x3f, sizeof f);
f[7] = 1;
f[31] = 1;
f[365] = 1;
for (int i = 0; i < 3; i++)
{
for (int j = arr[i]; j <= 79205; j++)
{
f[j] = min(f[j], f[j - arr[i]] + 1);
}
}
}
还有一种就是\(BFS\)写法,由于\(BFS\)具有最短路的性质,也就是第一次走到的点,就是最短的,也就是本题里面的最小天数
$Code$
void init2()
{
queue<int> q;
q.push(7);
q.push(31);
q.push(365);
f[7] = 1;
f[31] = 1;
f[365] = 1;
while (q.size())
{
int cur = q.front();
q.pop();
for (int i = 0; i < 3; i++)
{
if (cur + arr[i] <= 79205 and !f[cur + arr[i]])
{
f[cur + arr[i]] = f[cur] + 1;
q.push(cur + arr[i]);
}
}
}
}
本文来自博客园,作者:肆月初陸丶,转载请注明原文链接:https://www.cnblogs.com/zarttic/p/16502542.html

不坐牢!
浙公网安备 33010602011771号