【题解】CF6 合集

前言:

  1. 本人不会 LaTeX……请见谅
  2. 码风奇特,不喜勿喷哈
  3. 题面翻译取自 luogu,本蒟蒻也会安置原题链接
  4. 保证文章中不出现“显然”或者“注意到”,可能会出现“易证”
  5. AC 代码会放置在每一个题目的最底端,为防止 ban 码的情况出现,不设置跳转链接
  6. 有写错的地方欢迎各位神犇指正
  7. 本套题共 5 道,鉴于前几题可以直接做,预计阅读 + 理解时间小于 40min

正片开始!

CF6A

题面(可从下方链接跳转看原题题面):

给定 4 根木棍的长度,如果它们中存在 3 根木棍可以组成三角形,输出 TRIANGLE;如果它们无法组成三角形,但是它们中存在 3 根木棍可以组成退化的三角形(任意两边之和大于等于第三边,但是不是三角形),输出 SEGMENT ;否则,输出 IMPOSSIBLE

注意: 木棍不能折断,也不能只用一部分长度

题目传送门

序言 & 结论:

n≤4,怎么做都行……

难度:红题(建议直接水过)

推理过程:

  • 排序,直接枚举所有可能方案,并判断
  • 容斥也可行(杀鸡焉用牛刀?)

细节处理:

  • 退化的三角形……
  • 没排序 qwq

代码:

水题速切

点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int a[4],b[3],op;
void dfs(int cnt,int pos){
	if(cnt==3){
		if(b[0]+b[1]>b[2]){
			op=2;
		}
		if(b[0]+b[1]==b[2]&&!op){
			op=1;
		}
	}else{
		for(int i=pos;i<4;i++){
			b[cnt]=a[i];
			dfs(cnt+1,i+1);
		}
	}
	return;
}
int main(){
	for(int i=0;i<4;i++){
		scanf("%d",&a[i]);
	}
	sort(a,a+4);
	dfs(0,0);
	if(op==0){
		printf("IMPOSSIBLE\n");
	}
	if(op==1){
		printf("SEGMENT\n");
	}
	if(op==2){
		printf("TRIANGLE\n");
	}
	return 0;
}

----------------------------云落的分割线----------------------------

CF6B

题面(可从下方链接跳转看原题题面):

鉴于 luogu 翻译的不可读,此题不展示中文体面,抱歉!

题目传送门

序言 & 结论:

不是?

学过 bfs 的应该能瞬秒这个题

大型纪录片之《方向数组的来源》

难度:橙题

推理过程:

  • n,m≤100,直接枚举每个格子
  • 只要搜索到老板的办公桌,直接四个方向判断
  • 若是字母且不是老板自己的办公桌,就插入一个 set
  • set 的使用可以帮我们简化去重的部分

细节处理:

  • 不要用 scanf 输入字符矩阵
  • 四方向判断的时候注意是否在矩阵内(inbound)
  • 方向数组不要串

代码:

直接做《》——(自行脑补)

点击查看代码
#include<iostream>
#include<set>
using namespace std;
const int maxn=128;
const int dx[]={1,0,-1,0},dy[]={0,-1,0,1};
int n,m;
char c,mp[maxn][maxn];
set<char> s;
inline bool inbound(int x,int y){
	return x>=0&&x<n&&y>=0&&y<m;
}
int main(){
	cin>>n>>m>>c;
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			cin>>mp[i][j];
		}
	}
	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			for(int k=0;k<4;k++){
				if(mp[i][j]==c){
					int x=i+dx[k],y=j+dy[k];
					if(inbound(x,y)&&mp[x][y]!='.'&&mp[x][y]!=c){
						s.insert(mp[x][y]);
					}
				}
			}
		}
	}
	cout<<s.size()<<endl;
	return 0;
}

----------------------------云落的分割线----------------------------

CF6C

题面(可从下方链接跳转看原题题面):

n 个糖,a 从前往后吃,b 从后往前吃,每个糖都有吃完需要的时间,每个人在同一时间只能吃一个,吃完某一个后,才能吃下一个,如果两个人同时开始吃同一个,b 会让给 a,问最后每个人总共吃了多少糖

题目传送门

序言 & 结论:

对于 chocolate 的翻译如它的译文——“糖”

难度:橙题

差点刷新我的最快切题记录

无压行,共计 21 行,如何呢?

推理过程:

  • 两句话秒了(算上这句)
  • 维护指针,直接模拟,不断更新

细节处理:

代码:

云追不上雨,我追不上她

点击查看代码
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=1e5+10;
int n,a[maxn];
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	int pos1=1,pos2=n,sum1=0,sum2=0;
	while(pos1<=pos2){
		if(sum1<=sum2){
			sum1+=a[pos1++];
		}else{
			sum2+=a[pos2--];
		}
	}
	printf("%d %d\n",pos1-1,n-pos2);
	return 0;
}

----------------------------云落的分割线----------------------------

CF6D

题面(可从下方链接跳转看原题题面):

有一队人,第 i 个人的血量为 hi,你可以用火球点某个人,会对当前的人造成 a 点伤害,对旁边的人造成 b 点伤害

火球不能打 1 号和 n 号,求最少多少发火球烧死所有人

题目传送门

序言 & 结论:

题目终于不水了呢!

难度:绿题

可是范围很小,n≤10

推理过程:

  • dp 让我很暴戾,所以我打了个 dfs
  • 最简单的 dfs,形如:dfs(x) 表示对 x 号造成伤害……
  • 没 ~ 有 ~ 任 ~ 何 ~ 前 ~ 途 ~
  • 诶?突然发现——
  • 如果增加一个维度,即 dfs(x,k),表示对 x 号造成 k 次伤害……
  • 大大优化了时间复杂度,交一发……TLE
  • 考虑每次我们判断边界的时候都会遍历整个数组(效率非常低下)
  • 注意到造成伤害的时候?只与左右相关!
  • 即第 i 个人最多会连带受到第 i−1,i,i+1 三个人的伤害,之后就跟他没有关系了,所以我们到第 i+1 人的时候判断第 i 人是否死亡了,这样就能保证每个人最终都符合要求
  • 加入最优性剪枝

细节处理:

  • 最后到边界的时候要判断第 n−1 和 第 n 个人是否符合要求
  • 回溯!一定要把更新过的全部回溯!
  • 剪枝之后要写 return(本蒟蒻神秘的挂分方式)

代码:

码量不大,建议手敲,反对 ban 码

点击查看代码
#include<iostream>
using namespace std;
const int maxn=16,maxl=150+10;
int n,a,b,h[maxn];
int step[maxl],c[maxl],ans=2147483647;
inline void dfs(int k,int p){
	if(p>=ans){
		return;
	}
	if(k>=n){
		if(h[k]>=0||h[n]>=0){
			return;
		}
		ans=p;
		for(int i=1;i<=p;i++){
			step[i]=c[i];
		}
		return;
	}
	for(int i=0;i<=max(h[k]/a+1,max(h[k-1]/b+1,h[k+1]/b+1));i++){
		if(h[k-1]-i*b>=0){
			continue;
		}
		h[k]-=i*a;
		h[k-1]-=i*b;
		h[k+1]-=i*b;
		for(int j=p+1;j<=p+i+1;j++){
			c[j]=k;
		}
		dfs(k+1,p+i);
		h[k]+=i*a;
		h[k-1]+=i*b;
		h[k+1]+=i*b;
	}
	return;
}
int main(){
	scanf("%d%d%d",&n,&a,&b);
	for(int i=1;i<=n;i++){
		scanf("%d",&h[i]);
	}
	dfs(2,0);
	printf("%d\n",ans);
	for(int i=1;i<=ans;i++){
		printf("%d ",step[i]);
	}
	return 0;
}

----------------------------云落的分割线----------------------------

CF6E

题面(可从下方链接跳转看原题题面):

题目传送门

序言 & 结论:

相信各位已经被前面的水题恶心的不要不要的了

来一发蓝题助助兴

先捧一句:STL 大法好!

推理过程:

  • 插入一个桶啊
  • 维护小区间呀
  • 滑动窗口牛啊
  • 不合法就删呀
  • 队列往里塞啊
  • 输出不要错呀
  • 1要特判啊
  • STL 大法好呀

细节处理:

  • *s.rbegin() - *s.begin() > k,这是一个悲伤的故事
  • 论 #include < multiset >

代码:

备花备花!

点击查看代码
#include<iostream>
#include<cstdio>
#include<queue>
#include<set>
using namespace std;
const int maxn=1e5+10;
int n,k,a[maxn],ans;
queue<int> q;
multiset<int> s;
int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
	if(n==1){
		printf("%d %d\n%d %d\n",1,1,1,1);
		return 0;
	}
	int len=1;
	s.insert(a[1]);
	for(int i=2;i<=n;i++){
		s.insert(a[i]);
		while(i-len+1>=2&&*s.rbegin()-*s.begin()>k&&len<i){
			s.erase(s.find(a[len]));
			len++;
		}
		if(i-len+1==ans){
			q.push(i);
		}
		if(i-len+1>ans){
			ans=i-len+1;
			while(!q.empty()){
				q.pop();
			}
			q.push(i);
		}
	}
	if(ans!=1){
		printf("%d %d\n",ans,q.size());
	}else{
		printf("%d %d\n%d %d\n",ans,n,1,1);
	}
	while(!q.empty()){
		printf("%d %d\n",q.front()-ans+1,q.front());
		q.pop();
	}
	return 0;
}

完结撒花!

posted @   sunxuhetai  阅读(151)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示