首页 > 其他分享 >Codeforces Round #842 (Div. 2)

Codeforces Round #842 (Div. 2)

时间:2023-01-06 20:44:38浏览次数:55  
标签:842 int void Codeforces long vis solve Div include

题目链接

A

核心思路:样例模拟出答案。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 3e5 + 10,INF=0x3f3f3f3f, mod = 998244353;
void solve()
{
	LL n;
	cin >> n;
	cout << n - 1 << endl;
}

int main()
{
	int T;
    T = 1;
	cin >> T;

	while (T--)
	{
		solve();
	}
}

B

核心思路:这个题目的关键是需要找出相对顺序,找出来需要我们操作的数。 我们可以操作的数就是不符合相对顺序的长度。总的来说这个题目还是有点玄学,就是属于有那个感觉了,但是不知道怎么去操作。注意别想复杂就好了。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 3e5 + 10,INF=0x3f3f3f3f, mod = 998244353;
int a[N];
void solve()
{
	int n, k;
	cin >> n >> k;
	for (int i = 1;i <= n;i++)
	{
		cin >> a[i];
	}
	int cnt = 1;
	for (int i = 1;i <= n;i++)
	{
		if (a[i] == cnt)
		{
			cnt++;
		}
	}
	double t = (double)(n - cnt + 1) / k;
	double ans = ceil(t);
	cout << ans << endl;
}

int main()
{
	int T;
    T = 1;
	cin >> T;

	while (T--)
	{
		solve();
	}
}

C

核心思路:这个题目刚开始确实不知道怎么去构造,但是我们通过模拟样例可以发现,应该是需要构造的数列p中某一个数不可以超过2可以等于2.这是我们发现的第一个性质,然后再去思考另外一种无解的情况,也就是1 1.这个又是为什么无解呢,其实我们可以发现前i个位置,我们可以检查前i个数出现的次数,如果是大于i那么也肯定无解。因为我们的位置塞不下这么多数了。

好了,讨论了无解的情况,接下来去像怎么去构造有解的情况。

  • 某个数出现的次数为2的构造:我们可以假设是i,j这两个位置出现了次数是2的情况。那我们可以寻找第一个小于等于b[i]的那个没有出现的数进行这个位置的填补。
  • 然后其他次数为1的构造:这个我们可以利用max的性质,也就是\(max(x,x)=x,可重复贡献性\)。就是两个位置都填b[i].

下面看下模拟的实例模拟吧。

需要构造的数组p:1 3 4 3 5
ans1:1 2 4 3 5
ans2:1 3 4 2 5
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 3e5 + 10,INF=0x3f3f3f3f, mod = 998244353;
int a[N],ans1[N],ans2[N];//st里面存的是st[x]=y.
void solve()
{
	int n;
	cin >> n;
	for (int i = 1;i <= n;i++)
		cin >> a[i];
	vector<int> v;//这个里面放的是从来没有出现的数.
	map<int, int> mp,st;
	for (int i = 1;i <= n;i++)
	{
		mp[a[i]]++;
		if (mp[a[i]] > 2)
		{
			cout << "NO" << endl;return;
		}
	}
	int cur = 0;
	for (int i = 1;i <= n;i++)
	{
		cur += mp[i];
		if (!mp[i])
		{
			v.push_back(i);
		}
		if (cur > i)
		{
			cout << "NO" << endl;
			return;
		}
	}
	for (int i = 1;i <= n;i++)
	{
		if (mp[a[i]] ==  1)
		{
			ans1[i] = a[i];
			ans2[i] = a[i];
			continue;
		}
		if (!st[a[i]])
		{
			auto it = lower_bound(v.begin(), v.end(), a[i]);
			if (it == v.begin())
			{
				cout << "NO" << endl;
				return;
			}
			it--;
			ans1[i] = *it;
			st[a[i]] = ans1[i];
			ans2[i] = a[i];
			v.erase(it);
		}
		else
		{
			ans1[i] = a[i];
			ans2[i] = st[a[i]];
		}
	}
	cout << "YES" << endl;
	for (int i = 1;i <= n;i++)
	{
		cout << ans1[i] << " ";
	}
	cout << endl;
	for (int i = 1;i <= n;i++)
	{
		cout << ans2[i] << " ";
	}
	cout << endl;
}

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

其实对于构造问题,二分求我们的构造的数用得比较多.


D

核心思路:这是一个求逆序对的题目,所以我们可以联想置换环来进行求解。

现在引入置换环的一些前置知识吧:

置换环可以得到数组排序的一个最小次数,主要思想是:将我们的每个节点指向其排序后应该存放的位置,最终首尾相接形成一个环,那么数组排序的最小的次数就是数组的长度-环的数目

所以我们在处理置换环的问题可以看成图论的问题。

但是这个题目还有一个性质:那就是相邻的两个环达到我们题目所需的条件只需要n-cur-1.

下面看ygg的图:

所以这个问题也就基本解决了。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 3e5 + 10,INF=0x3f3f3f3f, mod = 998244353;
int n, p[N], vis[N];
map<int, bool> ring;
bool flag = 0;
void dfs(int u)
{
	if (vis[u])
		return;
	int v = p[u];//这里表示的是u到v的一条边。
	ring[u] = 1;
	vis[u] = 1;
	if (ring[u - 1] || ring[u + 1])
		flag = 1;//相邻的位置有环.
	dfs(v);
}
void solve()
{
	cin >> n;
	for (int i = 1;i <= n;i++)
		cin >> p[i];
	memset(vis, 0, sizeof vis);
	int cur = 0;
	flag = 0;
	for (int i = 1;i <= n;i++)
	{
		if (!vis[i])
		{
			cur++;
			ring.clear();
			dfs(i);

		}
	}
	if (flag)
	{
		cout << n - cur - 1 << endl;
	}
	else
		cout << n - cur + 1 << endl;
}

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

标签:842,int,void,Codeforces,long,vis,solve,Div,include
From: https://www.cnblogs.com/xyh-hnust666/p/17031554.html

相关文章

  • Codeforces Round #842 (Div. 2) A-D
    比赛链接A题意给一个数\(k\)找到最大的\(x\),满足\(1\leqx<k\)且\(x!+(x-1)!\)是\(k\)的倍数。题解知识点:数学。猜测\(x=k-1\),证明\((k-1)!+(k-......
  • 1.6 vp Polynomial Round 2022 (Div. 1 + Div. 2, Rated, Prizes!)
    A-AddPlusMinusSign题意:给出01字符串,可以在每两个字符中间任意添加‘+’,‘-’。最后要使表达式的绝对值最小思路:设表达式的值为\(cnt\),若当前\(cnt\)大于\(0\),不管......
  • Codeforces Round #842 (Div. 2) A-C, 补D
    A.GreatestConvex题意:给定一个k,求一个小于k的数x,使得x!+(x-1)!是k的倍数分析:题目已经给出提示:y!=y⋅(y−1)!,输出n-1cout<<n-1<<endl......
  • Codeforces Round #842 (Div. 2) A-D题解
    比赛链接A、GreatestConvex非常的简单。根据样例直接猜是输出\(n-1\).上一个\(Python\)代码。T=int(input())whileT>0:T-=1n=int(input())......
  • B. Quick Sort【Codeforces Round #842 (Div. 2)】
    B.QuickSortYouaregivenapermutation【排列】†\(p\)oflength\(n\)andapositiveinteger\(k≤n\).Inoneoperation,you:Choose\(k\)distinctelement......
  • Codeforces Contest 1616
    A.IntegerDiversity直接用个map贪心,如果有相同的就反向即可。B.MirrorintheString这道题洛谷的翻译锅了,所以建议去看原题。考虑这样一个字符串baacc,那么答案显......
  • 「Codeforces」寒假训练 2023 #2
    A.YetAnotherPalindromeProblem原题链接#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintN=1e5+10;intt;intn;inta[N];i......
  • Codeforces Round #839 (Div. 3)题解
    C.DifferentDifferences(贪心)题意​ 给定\(k\),\(n\)\((2\lek\len\le40)\)。从\([1-n]\)中不重复地任选\(k\)个数组成一个数组,使这个数组的差分数组中不同的......
  • Educational Codeforces Round 11
    EducationalCodeforcesRound11https://codeforces.com/contest/660A.Co-primeArray\(1\)与任何数的\(gcd\)都为\(1\),直接在不符合条件的两点间塞就可以了#inc......
  • 1.4 vp Codeforces Round #838 (Div. 2)
    A-DivideandConquer题意:给出序列a,设b为a中元素总和。你可以选择a中任意元素,将它除以二(向下取整)。问最少需要多少次可以使b为偶数思路:将a划分为奇偶两个集合。a中偶数......