首页 > 其他分享 >CF339 题解

CF339 题解

时间:2023-07-14 17:46:47浏览次数:59  
标签:CF339 int 题解 top pos dfs using now

CF339 题解

这套题虽然是div2,但是具有一定的价值,这套题作为典型的div2题目,全套5道题都几乎用暴力方法解决,但是为什么这样是对的?令人深思。

A

红题,把个位数提出来再排序就好了。

#include<bits/stdc++.h>
using namespace std;
const int N = 105;
char s[N];
int n,num[N],tot = 0;
int main()
{
	scanf("%s",s + 1);
	n = strlen(s + 1);
 	for(int i = 1;i <= n;i++)
 	{
 		if(s[i] == '+') continue;
 		num[++tot] = s[i] - '0';
	}
	sort(num + 1,num + tot + 1);
	for(int i = 1;i <= tot - 1;i++) cout<<num[i]<<"+";
	cout<<num[tot];
	return 0;
}

B

路径只有一种,记录当前位置,下一个目标如果大于当前位置,就走小半圈,如果小于当前位置,就绕过1号节点一次,把距离加起来就好了。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
long long tp = 0;
int a[N],n,m;
int main()
{
	cin>>n>>m;
	for(int i = 1;i <= m;i++) cin>>a[i];
	int np = 1;
	for(int i = 1;i <= m;i++) tp += (np <= a[i] ? a[i] - np : a[i] + n - np),np = a[i];
	cout<<tp;
	return 0;
}

C

比赛才刚刚开始!

这道题其实可以导出一个\(dp\)做法,我们发现右边和左边差距不会太大,所以假设\(dp_{i,k,t}\)为前\(i\)个砝码,左边减右边的绝对值为\(k\)(毕竟我们只在乎这个对吧),第\(i\)个砝码是\(t\),是否能够达到。转移看\(i\)的奇偶性再看放哪边即可。但是我写挂了。

正解还是很逆天,首先提取出哪些砝码可以用,然后暴力从第一个开始\(dfs\),合格的砝码就放一个,然后换边,如果放完\(m\)个就输出方案,结束程序。

看上去是一个\(10^{1000}\)的暴力对吧?但是这玩意CF上跑了15ms。感觉本题的难度主要在于分析时间...

#include<bits/stdc++.h>
using namespace std;
int a[11],tot = 0,m,q[1005];
inline void dfs(int x,int ls,int rs,int last)
{
	if(x == m + 1)
	{
		puts("YES");
		for(int i = 1;i <= m;i++) cout<<q[i]<<" ";
		exit(0);
	}
	for(int i = 1;i <= tot;i++)
	{
		if(a[i] == last) continue;
		if(x & 1)
		{
			if(ls + a[i] > rs) q[x] = a[i],dfs(x + 1,ls + a[i],rs,a[i]);
		}
		else
			if(rs + a[i] > ls) q[x] = a[i],dfs(x + 1,ls,rs + a[i],a[i]);
	}
}
int main()
{
	char s[11];
	scanf("%s",s + 1);
	for(int i = 1;i <= 10;i++) if(s[i] == '1') a[++tot] = i;
	scanf("%d",&m);
	dfs(1,0,0,0);
	puts("NO");
	return 0;
}

D

感觉比较奇葩...

这个题我们发现它是\(2^n\)个(不然没法做),而且在每一层都是两两\(O(1)\)合并的规律。

分层...合并...

线段树!

所以从底层开始记录线段树高度,直接单点修改维护即可。板子题,CF特有的CD题难度逆序对

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int t[N * 4],dep[N * 4],n,m;
inline void pushup(int pos)
{
	if(dep[pos] & 1) t[pos] = t[pos << 1] | t[pos << 1 | 1];
	else t[pos] = t[pos << 1] ^ t[pos << 1 | 1];
}
inline void build(int l,int r,int pos)
{
	if(l == r)
	{
		cin>>t[pos];
		dep[pos] = 0;
		return;
	}
	int mid = (l + r) >> 1;
	build(l,mid,pos << 1);
	build(mid + 1,r,pos << 1 | 1);
	dep[pos] = dep[pos << 1] + 1;
	pushup(pos);
}
inline void modify(int l,int r,int x,int k,int pos)
{
	if(l == r)
	{
		t[pos] = k;
		return;
	}
	int mid = (l + r) >> 1;
	if(x <= mid) modify(l,mid,x,k,pos << 1);
	else modify(mid + 1,r,x,k,pos << 1 | 1);
	pushup(pos);
}
int main()
{
	cin>>n>>m;
	n = 1 << n;
	dep[1] = 0;
	build(1,n,1);
	int x,y;
	for(int i = 1;i <= m;i++)
	{
		cin>>x>>y;
		modify(1,n,x,y,1);
		cout<<t[1]<<endl;
	}
	return 0;
}

E

三步指的是题目保证三步有解(谴责翻译)。

考虑将这个变成一个逆序过程,即将原排列翻成\(1 \to n\)。我们手模可以发现只有和前后不连续的数字才有可能成为翻转的端点,所以我们可以在每一步找出这些端点,枚举当前步该以哪两个为端点翻转,\(dfs\)即可,每一步翻转最多制造4个这样的点,加上一头一尾,总共的情况数就大约有\(14^6 = 7529536\)个,可以通过此题。

#include<bits/stdc++.h>
using namespace std;
const int N = 1005;
pair<int,int> q[4];
int a[N],n;
inline bool sorted()
{
	for(int i = 1;i <= n;i++) if(a[i] != i) return 0;
	return 1;
}
inline void solve(int x)
{
	if(sorted())
	{
		cout<<x - 1<<endl;
		for(int i = x - 1;i >= 1;i--)
			cout<<q[i].first<<" "<<q[i].second<<endl;
		exit(0);
	}
	if(x >= 4) return;
	int now[15],top = 0;
	now[++top] = 1;
	now[++top] = n;
	for(int i = 2;i <= n;i++)
		if(abs(a[i] - a[i - 1]) > 1)
			now[++top] = i - 1,now[++top] = i;
	sort(now + 1,now + top + 1);
	top = unique(now + 1,now + top + 1) - (now + 1);
	for(int i = 1;i <= top;i++)
		for(int j = i + 1;j <= top;j++)
		{
			q[x] = make_pair(now[i],now[j]);
			reverse(a + now[i],a + now[j] + 1);
			solve(x + 1);
			reverse(a + now[i],a + now[j] + 1);
		}
}
int main()
{
	cin>>n;
	for(int i = 1;i <= n;i++)
		cin>>a[i];
	solve(1);
	return 0;
}

标签:CF339,int,题解,top,pos,dfs,using,now
From: https://www.cnblogs.com/TheLastCandy/p/17554606.html

相关文章

  • P1891 疯狂 LCM 题解
    一、题目描述:$T$ 组数据,每组数据给定$n$,求$\sum_{i=1}^{n}lcm(i,n)$数据范围:$1\leT\le3\times10^5,1\len\le1\times10^6$。 二、解题思路:个人觉得思维难度不大,只是要记住一个结论:$\sum_{d\midn}d=\frac{\varphi(n)\timesn}{2}$这个公式对......
  • VMware17无法连接USB设备的问题解决方案
    前言【前言都是废话,可以直接看解决方案】事情是这样的,最近在做IMX6ULL的开发,刚开始就遇到了这个拦路虎问题,我使用的闪迪的TF卡32GB的,搭配绿联的读卡器使用。在windows以及物理机装的archlinux都能正常识别并进行挂载,离谱的就是在虚拟机上识别不了。虚拟机版本:VMwareWorkstati......
  • CF1220F Gardener Alex 题解--zhengjun
    发现根节点一定是\(1\),所以考虑两边的子树深度,然后发现只需要考虑一段后缀或前缀的深度即可。所以循环位移后,可以从中间往两边构建笛卡尔树,实时维护深度即可。代码#include<bits/stdc++.h>usingnamespacestd;usingll=longlong;constintN=2e5+10;intn,a[N],ans[N];......
  • CF732E Sockets 题解
    功率是\(x\)的插座插入一个适配器后功率是\(y\),功率是\(y\)的插座插入一个适配器后功率是\(z\),那么相当于功率是\(x\)的插座插入两个适配器。一个电脑可以用功率小的插座插入较少的适配器表达,也可以用功率大的插座插入较多的适配器表达。这里功率大的插座必然能表达出功......
  • 题解 [NOIP2015 提高组] 运输计划
    题目链接闲话:虽说是紫题,但慢慢想还是完全没有问题的。由于\(m\)个运输计划同时开始,所以耗费时间就是最慢的飞船耗费的时间(即最长时间)。考虑到题目让求最短时间,也就是最长的最短,可以二分。考虑二分最长时间(记作\(k\)),那么将所有路径分成两类,一类是原来耗费的时间就小于等于\(......
  • QOJ 6504. CCPC Final 2022 D Flower's Land 2题解
    QOJ6504.CCPCFinal2022DFlower'sLand2题解题意简述给你一个只含\(0,1,2\)的序列,相邻两个相同的数字可以直接消掉。询问包含两种区间所有数\(+1\)并对\(3\)取模。求一段区间能否用上述消除方式消完。样例输入8901211012245236168168236......
  • yarn : 无法加载文件 E:\nodejs\yarn.ps1,因为在此系统上禁止运行脚本。问题解决
    1.在电脑的开始菜单中,搜索PowerShell ,然后以管理员身份运行,如下所示:2.以管理员身份运行后,会出现命令窗口,接下来,输入命令get-ExecutionPolicy 查看权限,会看到它的返回值是 Restricted ,意思是当前是禁用的。3.执行命令:set-ExecutionPolicyRemoteSigned,没有报错就......
  • CF1846D Rudolph and Christmas Tree 题解
    Decription一颗圣诞树由\(n\)个底边为\(d\),高度为\(h\)的等腰三角形组成,每个三角形以\(y\)轴为对称轴,底边均平行于\(x\)轴,三角形有可能重叠。给出\(n,d,h\)以及每个三角形底边与\(x\)轴的距离,求该圣诞树的面积。Solution如图,这是一棵圣诞树,其由两部分组成,完整......
  • NOI2021 题解
    [NOI2021]轻重边转化一下题意:每次给一条链染色,查一条链从\(x\)到\(y\)有几条边两端颜色相同。那这个随便树剖线段树就好了。也可以LCT,码量可能要小点。#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>usingnamespace......
  • 题解 最大加权矩阵
    题目链接虽然是一道橙题,但还是蕴含了重要算法思想——降维思想。如果是一维形式,即最大子段和,我们采取先求前缀和,并固定右端点,减去左边最小的办法求。对于这题,若固定了上下边界,则可以利用列的前缀和将其“压缩”为一维形式,再采取“最大子段和”的方式求解。如下面一个二维矩阵:......