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;
	}
}
相关推荐
仙俊红3 小时前
LeetCode487周赛T2,删除子数组后的最终元素
数据结构·算法
-dzk-9 小时前
【代码随想录】LC 59.螺旋矩阵 II
c++·线性代数·算法·矩阵·模拟
风筝在晴天搁浅9 小时前
hot100 78.子集
java·算法
Jasmine_llq9 小时前
《P4587 [FJOI2016] 神秘数》
算法·倍增思想·稀疏表(st 表)·前缀和数组(解决静态区间和查询·st表核心实现高效预处理和查询·预处理优化(提前计算所需信息·快速io提升大规模数据读写效率
超级大只老咪9 小时前
快速进制转换
笔记·算法
m0_7066532310 小时前
C++编译期数组操作
开发语言·c++·算法
故事和你9110 小时前
sdut-Java面向对象-06 继承和多态、抽象类和接口(函数题:10-18题)
java·开发语言·算法·面向对象·基础语法·继承和多态·抽象类和接口
qq_4232339010 小时前
C++与Python混合编程实战
开发语言·c++·算法
TracyCoder12310 小时前
LeetCode Hot100(19/100)——206. 反转链表
算法·leetcode
m0_7155753410 小时前
分布式任务调度系统
开发语言·c++·算法