CF每日4题(1500-1700)

经验+4

  • 103B 克苏鲁可爱捏+发现图点和边的数量规律
  • 1198A 滑动窗口
  • 255C 二维dp求最小值
  • 1496C a x = ⌈ a x a y ⌉ a_x=\lceil{a_x\over a_y}\rceil ax=⌈ayax⌉,用 \sqrt{} 优化次数

103B 图 并查集1500

cpp 复制代码
const int N=1e6+10,mod=1e9+7,inf=1e9+10;
int fa[N];
int findf(int x){
	if(fa[x]==x)return x;
	return fa[x]=findf(fa[x]);
}
void merge(int x,int y){
	int fx=findf(x),fy=findf(y);
	if(fx==fy)return;
	fa[fy]=fa[fx];
}
void solve(){
	int n,m;cin>>n>>m;
	forr(i,1,n)fa[i]=i;
	forr(i,1,m){
		int u,v;
		cin>>u>>v;
		merge(u,v);
	}
	if(n==m){//使用并查集确认是不是只有一个连通块
		int fg=0;
		forr(i,1,n)fg+=(fa[i]==i);
		
		cout<<(fg==1?"FHTAGN!":"NO")<<endl;
	}else cout<<"NO"<<endl;
}

1198A 滑动窗口 1600

题意:改变最少的数,让数组中的不同数值数为给定值

注意留下的数应该大小上是连续的,因为强度值要在 [ l , r ] [l,r] [l,r]范围内

所以采用滑动窗口

cpp 复制代码
map<int,int>mp;
set<int>s;
void solve(){
	int n,m;cin>>n>>m;
	vector<int>a(n+1);

	forr(i,1,n){
		cin>>a[i];
		mp[a[i]]++;
		s.insert(a[i]);
	}
	
	int k=8*m/n;
	if(k>=31)return cout<<0<<endl,void();//2^k>4e5 溢出输出0
	k=(1<<k);//最大种数
	if(k>=s.size())return cout<<0<<endl,void();//可以容下全部数 不用改
	
	//滑动窗口
	int ans=0,sm=0;
	auto l=s.begin(),r=s.begin();
	forr(i,1,k){
		sm+=mp[*r];
		r++;
	}
	while (r!=s.end())
	{
		sm=sm-mp[*l]+mp[*r];
		l++,r++;
		ans=max(sm,ans);
	}
	cout<<n-ans<<endl;
}

225C dp 1700

cpp 复制代码
//从前向后 收集型
//从i-1更新i i可以变色,或延续不变色
string s[N];
int cnt[N][2],dp[N][N][2];//第i列 宽度j 颜色c
void solve(){
	int n,m,x,y;cin>>n>>m>>x>>y;
	memset(dp,0x3f,sizeof dp);//要求最小值,注意初始化为inf
	forr(i,1,n){
		cin>>s[i];
		s[i]=' '+s[i];
	}
	forr(i,1,m){
		forr(j,1,n){
			cnt[i][0]+=(s[j][i]=='.');
			cnt[i][1]+=(s[j][i]=='#');
		}
	}

	dp[1][1][0]=cnt[1][0],dp[1][1][1]=cnt[1][1];//第一个不用看前面的状态
	forr(i,2,m){
		forr(c,0,1){
			forr(j,x,y){//变色
				dp[i][1][c]=min(dp[i-1][j][c^1]+cnt[i][c],dp[i][1][c]);
			}
			forr(j,2,y){//不变色
				dp[i][j][c]=dp[i-1][j-1][c]+cnt[i][c];
			}
		}
	}
	
	int ans=0x3f3f3f3f;
	forr(j,x,y){
		ans=min({dp[m][j][0],dp[m][j][1],ans});
	}
	cout<<ans<<endl;
}

另有dalao前面更新后面的思路

1469C 思维 数学 1700


有点红温,死磕log的处理方法,但是 l o g 2 2 e 5 > 17 log_22e5>17 log22e5>17,一直想着怎么优化才好,没换个思路。

看题解发现利用 n \sqrt n n 就好,2e5五层 \sqrt{} 就到1了

  • ⌈ i i + 1 ⌉ = 1 \lceil{i\over{i+1}}\rceil =1 ⌈i+1i⌉=1
  • n \sqrt n n 和 n n n之间的数选 y = n y=n y=n就可以
  • n = n n n=\sqrt n \sqrt n n=n n ,多操作一下,n就能变1
  • n \sqrt n n 由 n \sqrt {\sqrt n} n 两次解决
cpp 复制代码
struct pr
{
	int x,y;
};
void solve(){
	int n;
	cin>>n;
	vector<pr>ans;
	while (n>2)
	{
		int q=ceil(sqrt(n));
		forr(i,q+1,n-1)ans.push_back({i,i+1});
		ans.push_back({n,q});
		ans.push_back({n,q});
		n=q;
	}
	cout<<ans.size()<<endl;
	for(auto i:ans){
		cout<<i.x<<' '<<i.y<<endl;
	}
}
相关推荐
省四收割者28 分钟前
Go语言入门(10)-数组
数据结构·经验分享·笔记·vscode·算法·golang
lxmyzzs41 分钟前
【图像算法 - 21】慧眼识虫:基于深度学习与OpenCV的农田害虫智能识别系统
人工智能·深度学习·opencv·算法·yolo·目标检测·计算机视觉
KeithTsui42 分钟前
GCC C语言整数转换的理解(Understanding of Integer Conversions in C with GCC)
c语言·开发语言·算法
jiunian_cn1 小时前
【Linux】线程
android·linux·运维·c语言·c++·后端
firshman_start1 小时前
文件包含的学习笔记
笔记·学习
jdlxx_dongfangxing2 小时前
C++ 序列式容器深度解析:vector、string、deque 与 list
c++·stl
月盈缺2 小时前
学习嵌入式的第二十四天——数据结构——队列和树
数据结构·学习
rainy雨2 小时前
学习方法①
学习
欧阳小猜3 小时前
深度学习②【优化算法(重点!)、数据获取与模型训练全解析】
人工智能·深度学习·算法
小欣加油3 小时前
leetcode 904 水果成篮
c++·算法·leetcode