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\)
有两个式子

\[ed = rd \times P \mod M \\ rd = ed \times Q \mod 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]);
			}
		}
	}
}

:name

posted @ 2022-07-23 01:09  肆月初陸丶  阅读(45)  评论(0)    收藏  举报