Loading

Codeforces Round 997 (Div. 2)



A - Shape Perimeter

题意

一个\(m×m\)的图章的左下角与坐标纸的左下角对齐,接下来\(n\)好,每行给出\(x\ y\),将图章向右移\(x\)个单位长度,想上移\(y\)个单位长度,每次移动结束后,图章会在纸上留下一个\(m×m\)的色块。求最终纸上图形的周长(保证色块是封闭图形)

思路

由于是封闭图形,最后的周长就是两个方向移动的距离加上自身的长度的两倍

代码

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 1e6 + 5;

void solve()
{
	int n, m;
	cin >> n >> m;
	int x = 0, y = 0;
	for (int i = 0; i < n; i++)
	{
		int a, b;
		cin >> a >> b;
		if (!i)
		{
			continue;
		}
		x += a;
		y += b;
	}
	cout << (x + m + y + m) * 2 << endl;
}

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

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

	return 0;
}

B - Find the Permutation

题意

以领接矩阵的形式给出一个\(n\)哥定点的无向图,构造一个序列\(p\),使得这个无向图满足下列条件:对于\(i,j(i<j)\)当且精当\(p_i<p_j\),点\(p_i\)和点\(p_j\)间才有边

思路

\(p_i,p_j\)之间有边时,序列中\(p_i\)一定在\(p_j\)右边,反之则在左边。那就可以先把\(1\)推入双端队列遍历之后的点,两者之间右边则往队尾放,否则往队头放;如果中间有其他元素则要按前面的方法改变雷元素的位置

代码

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 1e6 + 5;

void solve()
{
	int n;
	cin >> n;
	vector<vector<char>> v(n + 1, vector<char>(n + 1));
	deque<int> ans;
	getchar();
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			v[i][j] = getchar();
		}
		getchar();
	}
	ans.push_back(1);
	for (int i = 2; i <= n; i++)
	{
		if (v[1][i] == '1')
		{
			stack<int> s;
			while (true)
			{
				int j = ans.back();
				if (v[i][j] == '1')
				{
					ans.push_back(i);
					while (s.size())
					{
						ans.push_back(s.top());
						s.pop();
					}
					break;
				}
				s.push(j);
				ans.pop_back();
			}
		}
		else
		{
			stack<int> s;
			while (true)
			{
				int j = ans.front();
				if (v[i][j] == '0')
				{
					ans.push_front(i);
					while (s.size())
					{
						ans.push_front(s.top());
						s.pop();
					}
					break;
				}
				s.push(j);
				ans.pop_front();
			}
		}
	}
	while (ans.size())
	{
		cout << ans.front() << " ";
		ans.pop_front();
	}
	cout << endl;
}

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

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

	return 0;
}


C - Palindromic Subsequences

题意

构造一个长度为\(n\)的整数序列\(A(1\le A_i\le n)\),使得\(A\)的最长回文子序列的数量大于\(n\)

思路

最长回文子序列越短,越容易使之数量越多。不仿构造出最长回文子序列长度为\(3\)的序列,这样就容易满足题意。对于\(1\ 2\ 3\ 4\ 5\ 6\)怎么样才能使之产生回文?可以将\(6\)改为\(1\),得到\(1\ 2\ 3\ 4\ 5\ 1\),但此时最长回文子序列长度为\(6\),显然不符合题意,我们可以再将\(2\)改成\(1\),得到\(1\ 1\ 3\ 4\ 5\ 1\),这样就破坏了原序列的对称性,最长回文子序列的长度也变为了\(3\),数量也变成了\(7\),满足题意。按这种方法构造的序列,最长回文子序列的数量为\(1+2×(n-3)=2n-5\),在\(n\ge 6\)时是成立的

代码

点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int, int> pii;

const int mxn = 1e6 + 5;

void solve()
{
	int n;
	cin >> n;
	cout << "1 1 ";
	for (int i = 3; i <= n - 1; i++)
	{
		cout << i - 1 << " ";
	}
	cout << 1 << endl;
}

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

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

	return 0;
}



比赛链接 https://mirror.codeforces.com/contest/2056

posted @ 2025-01-24 17:12  _SeiI  阅读(21)  评论(0)    收藏  举报