2024.2.4 寒假训练记录(18)

这几天状态一直不太好,训练量比自己预期的要差一大截,焦虑,希望明天可以恢复过来

文章目录

  • 牛客 寒假集训1F 鸡数题!
  • 牛客 寒假集训1J 又鸟之亦心
  • 牛客 寒假集训1K 牛镇公务员考试
  • ATC ABC339D Synchronized Players

牛客 寒假集训1F 鸡数题!

题目链接

关于第二类斯特林数看这里

#include 

using namespace std;

#define int long long
using i64 = long long;

typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;

const int N = 1000010;
const int maxn = 1e6 + 1;
const int mod = 1e9 + 7;

int Jc[maxn];

void calJc()
{
    Jc[0] = Jc[1] = 1;
    for(int i = 2; i < maxn; i++) Jc[i] = Jc[i - 1] * i % mod;
}

int pow(int a, int n, int p)
{
    int ans = 1;
    while (n)
    {
        if (n & 1) ans = ans * a % p;
        a = a * a % p;
        n >>= 1;
    }
    return ans;
}

int niYuan(int a, int b)
{
    return pow(a, b - 2, b);
}

int C(int a, int b)
{
    if(a < b) return 0;
    return Jc[a] * niYuan(Jc[b], mod) % mod * niYuan(Jc[a - b], mod) % mod;
}

int S(int n, int k)
{
	int res = 0;
	for (int i = 0; i <= k; i ++ )
	{
		if (i & 1) res = (res - (C(k, i) * pow(k - i, n, mod)) % mod) % mod;
		else res = (res + (C(k, i) * pow(k - i, n, mod)) % mod) % mod;
	}
	while (res < 0) res += mod;
	res = res * niYuan(Jc[k], mod) % mod;
	return res;
}

void solve()
{
	calJc();
	int n, m;
	cin >> n >> m;
	cout << S(n, m) << '\n';
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);

	int t = 1;
	// cin >> t;
	while (t -- )
	{
		solve();
	}
}

牛客 寒假集训1J 又鸟之亦心

题目链接

参考jiangly代码,二分,check中遍历所有任务,假设一个人在a[i]时看另一个人有多少种位置可以选,存在set里,set如果在某一个时刻为空就说明此mid是不行的

#include 

using namespace std;

#define int long long
using i64 = long long;

typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;

const int N = 1000010;
const int maxn = 1e6 + 1;
const int mod = 1e9 + 7;

void solve()
{
	int n, x, y;
	cin >> n >> x >> y;
	vector<int> a(n);
	for (int i = 0; i < n; i ++ ) cin >> a[i];

	auto check = [&](int mid)
	{
		int lst = y;
		set<int> st;
		if (abs(x - y) > mid) return false;
		st.insert(x);

		for (int i = 0; i < n; i ++ )
		{
			if (abs(lst - a[i]) <= mid) st.insert(lst);
			while (!st.empty() && abs((*st.begin()) - a[i]) > mid) st.erase(*st.begin());
			while (!st.empty() && abs((*st.rbegin()) - a[i]) > mid) st.erase(*st.rbegin());
			lst = a[i];
			if (st.empty()) return false;
		}
		return true;
	};

	int l = 0, r = 1e9;
	while (l < r)
	{
		int mid = l + r >> 1;
		if (check(mid)) r = mid;
		else l = mid + 1;
	}
	cout << r << '\n';
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);

	int t = 1;
	// cin >> t;
	while (t -- )
	{
		solve();
	}
}

牛客 寒假集训1K 牛镇公务员考试

题目链接

基环内向树(准确的说应该是森林)

编号 i 向 a[i] 连边,表示对其限制,我们可以发现环之外的链对答案没什么影响,因为确定了环上一点,可以倒推出链上的所有答案(原因就是约束关系),所以我们在环上任取一点,枚举这个点的五种答案,然后遍历一下环看这个答案是否合法

因为不保证联通,所以需要遍历每一个点

这题还学到了一个技巧,截取vector的一部分可以直接a = {迭代器头,迭代器尾}(截取出的部分不包括尾部迭代器)

#include 

using namespace std;

#define int long long
using i64 = long long;

typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;

const int N = 1000010;
const int maxn = 1e6 + 1;
const int mod = 998244353;

void solve()
{
	int n;
	cin >> n;
	vector<int> a(n + 1);
	vector<string> s(n + 1);
	for (int i = 1; i <= n; i ++ ) cin >> a[i] >> s[i];
	vector<bool> st(n + 1);
	int ans = 1;
	for (int i = 1; i <= n; i ++ )
	{
		if (st[i]) continue;
		int j = i;
		vector<int> huan;
		for (; !st[j]; j = a[j])
		{
			huan.push_back(j);
			st[j] = true;
		}
		auto iter = find(huan.begin(), huan.end(), j);
		if (iter == huan.end()) continue;
		huan = {iter, huan.end()};
		int tmp = 0;
		for (int k = 0; k < 5; k ++ )
		{
			int h = k;
			for (auto t : huan) h = (int)(s[t][h] - 'A');
			tmp += h == k;
		}
		ans = ans * tmp % mod;
	}
	cout << ans << '\n';
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);

	int t = 1;
	// cin >> t;
	while (t -- )
	{
		solve();
	}
}

ATC ABC339D Synchronized Players

题目链接

BFS,用四维数组,dist[i][j][k][z] 表示第一个人在i,j 第二个人在k,z 时的最短路径长度(其他四维数组定义类似)

#include 

using namespace std;

#define int long long
using i64 = long long;

typedef pair<int, int> PII;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;

const int N = 1000010;
const int maxn = 1e5 + 1;
const int mod = 1e9 + 7;

int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};

void solve()
{
	int n;
	cin >> n;
	vector<vector<char>> g(n + 1, vector<char>(n + 1));
	PII start = {0, 0}, end = {0, 0};
	for (int i = 1; i <= n; i ++ )
		for (int j = 1; j <= n; j ++ )
		{
			cin >> g[i][j];
			if (g[i][j] == 'P')
			{
				if (start.first == 0) start = make_pair(i, j);
				else end = make_pair(i, j);
			}
		}
	vector<vector<vector<vector<int>>>> dist(n + 1, vector<vector<vector<int>>>(n + 1, vector<vector<int>>(n + 1, vector<int>(n + 1, 0x3f3f3f3f3f3f3f3f))));
	vector<vector<vector<vector<bool>>>> st(n + 1, vector<vector<vector<bool>>>(n + 1, vector<vector<bool>>(n + 1, vector<bool>(n + 1))));
	queue<pair<PII, PII>> q;
	q.push({start, end});
	dist[start.first][start.second][end.first][end.second] = 0;
	st[start.first][start.second][end.first][end.second] = true;
	while (!q.empty())
	{
		auto xs = q.front().first.first, ys = q.front().first.second;
		auto xe = q.front().second.first, ye = q.front().second.second;
		q.pop();

		for (int i = 0; i < 4; i ++ )
		{
			int xsn = xs + dx[i], xen = xe + dx[i];
			int ysn = ys + dy[i], yen = ye + dy[i];
			xsn = max(xsn, (i64)1); xsn = min(xsn, n);
			xen = max(xen, (i64)1); xen = min(xen, n);
			ysn = max(ysn, (i64)1); ysn = min(ysn, n);
			yen = max(yen, (i64)1); yen = min(yen, n);
			if (g[xsn][ysn] == '#') xsn = xs, ysn = ys;
			if (g[xen][yen] == '#') xen = xe, yen = ye;

			if (st[xsn][ysn][xen][yen]) continue;
			st[xsn][ysn][xen][yen] = true;
			dist[xsn][ysn][xen][yen] = dist[xs][ys][xe][ye] + 1;
			q.push({{xsn, ysn}, {xen, yen}});
		}
	}

	int ans = 0x3f3f3f3f3f3f3f3f;
	for (int i = 1; i <= n; i ++ )
	{
		for (int j = 1; j <= n; j ++ )
		{
			ans = min(ans, dist[i][j][i][j]);
		}
	}
	if (ans == 0x3f3f3f3f3f3f3f3f) cout << -1 << '\n';
	else cout << ans << '\n';
}

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0);

	int t = 1;
	// cin >> t;
	while (t -- )
	{
		solve();
	}
}

你可能感兴趣的:(2024寒假训练记录,算法)