首页 > 其他分享 >CF 981 Review

CF 981 Review

时间:2024-10-25 13:01:11浏览次数:1  
标签:10 int Review 981 CF re while wr void

CF 981 Review

打的最差的一场 Div.3

虽然可能有Div.3是ICPC赛制的原因,但是本质上还是自己太菜了。

A

模拟

Code

#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void re(T &x)
{
	x=0;int f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	x*=f;
}
template<typename T>inline void wr(T x)
{
	if(x<0)putchar('-'),x=-x;
	if(x>9)wr(x/10);
	putchar(x%10^48);
}
int n,m,T;
int main()
{
	re(T);
	while(T--)
	{
		re(n);
		int pos=0,upd=-1;
		while(1)
		{
			pos+=upd;
			if(pos<-n||pos>n)
			{
				puts(upd<0?"Sakurako":"Kosuke");
				break;
			}
			if(upd<0)upd=-upd+2;
			else upd=-upd-2;
		}
	}
	return 0;
}

B

稍微难写一点的模拟

Code

#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void re(T &x)
{
	x=0;int f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	x*=f;
}
template<typename T>inline void wr(T x)
{
	if(x<0)putchar('-'),x=-x;
	if(x>9)wr(x/10);
	putchar(x%10^48);
}
int n,m,T;
const int N=1000;
int mp[N][N];
inline int expand(int x,int y)
{
	int ans=0;
	for(;1<=x&&x<=n&&1<=y&&y<=n;x++,y++)
		if(mp[x][y]<0)ans=min(ans,mp[x][y]);
	return -ans;
}
int main()
{
	re(T);
	while(T--)
	{
		re(n);
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j)
				re(mp[i][j]);
		long long ans=0;
		for(int st=1;st<=n;++st)
			ans+=expand(st,1);
		for(int st=2;st<=n;++st)
			ans+=expand(1,st);
		wr(ans),putchar('\n');
	}
	return 0;
}

C

分析

据锚具所说应该是可以直接构造,但是我还是没有想出来,不过对于我来,即使DP的水平确实很低,但是这个DP还是很显然的吧。

拆成两半分开进行DP,把“是否交换”塞进状态里,然后最后合起来的时候统计一下合并的代价就好了。

Code

#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void re(T &x)
{
	x=0;int f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	x*=f;
}
template<typename T>inline void wr(T x)
{
	if(x<0)putchar('-'),x=-x;
	if(x>9)wr(x/10);
	putchar(x%10^48);
}
int n,m,T;
const int N=2e5+10,INF=2005120700;
int a[N];
int check(int x,int y)
{
	return x==y;
}
int main()
{
	re(T);
	while(T--)
	{
		re(n);
		for(int i=1;i<=n;++i)re(a[i]);
		vector<vector<int>>dp(n+1,vector<int>(3,INF));
		dp[0][0]=dp[0][1]=0;
		a[0]=a[n+1]=0; 
		for(int i=1;i<=n/2;++i)
		{
			dp[i][0]=min(dp[i-1][0]+check(a[i],a[i-1])+check(a[n-i+1],a[n-i+2]),dp[i][0]);
			dp[i][0]=min(dp[i-1][1]+check(a[i],a[n-i+2])+check(a[n-i+1],a[i-1]),dp[i][0]);
			dp[i][1]=min(dp[i-1][0]+check(a[n-i+1],a[i-1])+check(a[i],a[n-i+2]),dp[i][1]);
			dp[i][1]=min(dp[i-1][1]+check(a[n-i+1],a[n-i+2])+check(a[i],a[i-1]),dp[i][1]);
		}
		if(n&1)
			wr(min(dp[n/2][0],dp[n/2][1])+check(a[n+1>>1],a[n/2])+check(a[n/2+2],a[n+1>>1]));
		else
			wr(min(dp[n/2][0],dp[n/2][1])+check(a[n/2],a[n/2+1]));
		putchar('\n');
		
	}
	return 0;
}

D

最烦的一集,赛时四十分钟写完前三题,五十分钟想到D的DP做法,以为要上大分了,结果发现好像死活调不出来优化以后的做法,最后发现从暴力DP到优化后的DP需要多加一步初始化,实在是逆天,一直到最后两三分钟才改出来。

分析

也可以定义 \(dp[i][0/1]\) 为,考虑完前 \(i\) 个数 ,第 \(i\) 个是否作为右端点的最大合法段数,然后就很好 DP 了。

暴力做法是 \(O(N^2)\) 的,当然只需要开一个 map 来记录最大值就可以做到 \(O(n\log n)\) ,然而由于我实在是太喜欢 unordered_map 了,所以没写普通的 map ,导致赛后被卡了 umap ,hack 掉了 D 题,我真的会谢。

AC Code

#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void re(T &x)
{
	x=0;int f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	x*=f;
}
template<typename T>inline void wr(T x)
{
	if(x<0)putchar('-'),x=-x;
	if(x>9)wr(x/10);
	putchar(x%10^48);
}
int n,m,T;
const int N=2e5+10;
int s[N];
map<int,int>maxdp,vis;
int main()
{
	re(T);
	while(T--)
	{
		re(n);maxdp.clear(),vis.clear();
		for(register int i=1;i<=n;++i)re(s[i]),s[i]+=s[i-1];
		vector<vector<int>> dp(n+1,vector<int>(3,0));
		dp[0][0]=dp[0][1]=0,vis[0]=1;
		int ans=-1;
		for(register int i=1;i<=n;++i)
		{
			dp[i][0]=max(dp[i-1][0],dp[i-1][1]);
			if(vis[s[i]])dp[i][1]=maxdp[s[i]]+1;
			maxdp[s[i]]=max(maxdp[s[i]],max(dp[i][1],dp[i][0]));
			ans=max(ans,max(dp[i][1],dp[i][0]));
			vis[s[i]]=1;
		} 
		wr(ans),putchar('\n');
	}
	return 0;
}

E

还是挺考验思维的一道题,大概想一想的话,应该半个小时左右能做出来,但是这题放的位置似乎有点过于逆天了,通过数和 C 题差不多。

顺便吐槽一句,为什么 D 过的人比 C 多了这么多?

分析

可以很显然地想到,如果一个点,或者是一个点对已经符合条件了,那么我肯定不会去操作它/它们了。

那么又怎样通过最小的代价把剩下的进行操作呢?

可以想到通过“成对”的方式来构造,代价是最小的,而且也没有最小的代价了。(因为交换本就是基于“成对”而存在)

Code

#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void re(T &x)
{
	x=0;int f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	x*=f;
}
template<typename T>inline void wr(T x)
{
	if(x<0)putchar('-'),x=-x;
	if(x>9)wr(x/10);
	putchar(x%10^48);
}
int n,m,T;
const int N=1e6+10;
int p[N],id[N];
int main()
{
	re(T);
	while(T--)
	{
		re(n);
		for(register int i=1;i<=n;++i)
			re(p[i]),id[p[i]]=i;
		int ans=0,p1,p2;
		for(register int i=1;i<=n;++i)
		{
			if(p[i]==i||p[i]==id[i])continue;
			ans++;
			p1=i,p2=id[id[i]];
			id[p[p1]]=p2,id[p[p2]]=p1;
			swap(p[p1],p[p2]);
		}
		wr(ans),putchar('\n');
			
	}
	return 0;
}

总结

复杂度正确的时候,能直接用 map 就直接用 map,不要什么时候都写 umap,在数据极限的情况下单次操作可以被卡成 \(o(n)\)

标签:10,int,Review,981,CF,re,while,wr,void
From: https://www.cnblogs.com/Hanggoash/p/18502279

相关文章

  • 题解:CF722D Generating Sets
    涉及知识点:set。解题思路每次让列表中最大的元素缩小两倍,保证答案最优。如果当前的元素缩小成$0$就直接跳出循环,输出这个序列。由于序列需要支持插入、删除以及找最大值,所以这个序列可以用set来维护。代码#include<bits/stdc++.h>#defineintlonglong#definell......
  • 题解:CF1988B Make Majority
    题目大意题面写得很清楚,我就不再赘述了。解题思路涉及知识点:字符串,构造。由于所有相邻的$0$合并完会变成一个$0$,所以先贪心地把所有挨在一起的$0$合并起来,放在一个新的字符串里。而且题目需要你判断是否最终是否能合并成一个$1$,所以$1$是不需要想$0$一样合并的,这......
  • 题解:CF1994B Fun Game
    涉及知识点:异或,字符串处理。解题思路‌异或是一种二进制运算,用于比较两个数字的差异。当两个输入不同时,异或运算的结果为1;当两个输入相同时,结果为0。现在就可以切掉本题了。设两个字符串分别为$a$,$b$。如果$a$和$b$完全相同,输出Yes。如果$a$中没有$1$且$b$......
  • 题解:CF633D Fibonacci-ish
    涉及知识点:枚举,STL。题目大意给你一个序列,让你选出一些元素,使其构成fibonacccccci数列,求数列的最大长度。解题思路定义一个桶,$mp_i$代表$i$这个数在输入序列当中出现的次数。由于$n\le1000$,所以可以直接暴力枚举fibonacccccci数列的前两个数。前两个数固定了,这......
  • 题解:CF2030C A TRUE Battle
    LuoguLink|CodeforcesLink\(\texttt{Describe}\)给一个长度为\(n\)的二进制序列,Alice和Bob在相邻两个0/1中间分别加\(\operatorname{or}\)或\(\operatorname{and}\)操作,优先级满足\(\operatorname{and}>\operatorname{or}\)。Alice希望最后运算的值为\(1\),Bo......
  • 【Azure Function】Python Function部署到Azure后报错No module named '_cffi_backend
    问题描述本地使用Python编写的FunctionApp,发布到AzureFunction后,出现 _cffi_backendmodule无法找到的报错。ERROR:Error:Nomodulenamed'_cffi_backend',Cannotfindmodule.Pleasechecktherequirements.txtfileforthemissingmodule.Formoreinfo,plea......
  • CF35C. Fire Again 题解 bfs求最短路
    题目链接:https://codeforces.com/problemset/problem/35/C视频讲解:https://www.bilibili.com/video/BV1tZ1FYPELp/?p=4以每个着火的点为起点求最短路,然后输出任意一个距离值最大的点即可。需要注意的是:本题是文件输入输出。示例程序:#include<bits/stdc++.h>usingnamespace......
  • CF1139C. Edgy Trees 题解 并查集
    题目链接:https://codeforces.com/problemset/problem/1139/C视频讲解:https://www.bilibili.com/video/BV1tZ1FYPELp?p=3我们可以求总方案数-不满足条件的方案数。设一个不包含黑色边的极大连通块的大小为\(sz_i\)。则答案为\[n^k-\sum\{sz_i^k\}\]示例程序:#include......
  • CF1800E2. Unforgivable Curse (hard version) 题解 并查集
    题目链接:https://codeforces.com/contest/1800/problem/E2视频讲解:https://www.bilibili.com/video/BV1tZ1FYPELp?p=2把下标\(i\)对应到图中编号为\(i\)的节点。节点\(i\)和\(i+k\)之间连一条边,节点\(i\)和\(i+k+1\)之间也连一条边。同一个连通块里的节点对应的字......
  • Springboot计算机毕业设计滁州市电动车牌照管理系统cfc49
    Springboot计算机毕业设计滁州市电动车牌照管理系统本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表项目功能:用户,法律法规,车辆类型,牌照申请,可选牌号,上牌业务,上牌预约,选定牌号,挂失登记,牌照信息,牌照......