8.4 Codeforces练习

寒假打了几把cf差不多把基础分打满了,新手保护机制也要没了。之后的比赛必须得提高水平,要不然就要掉分了!所以今天的练习主要聚焦在1000靠上一点的题目。

B. Binary Typewriter

来源:Problem - 2103B - Codeforces

难度:1100

思路

这道是五月初训练的时候刷过的题,看记录当时交了好多发到最后都没过。本次也耗时30分钟左右,中间wa了一发。第二发过的时候有一个细节没梳理清楚,有点碰巧。在我总结的时候发现了。

  • 如果全为0直接输出长度
  • 如果全为1只用经过一次变换
  • 如果仅有1个1且在最后边(sum==1):0001,只用经过一次变换
  • 如果sum==2(仅有1个1且不在末尾)的话经过反转可以变成上一种情况
  • 其他一般情况(sum>=3)通过反转可以减少两次变换

代码

cpp 复制代码
void solve()
{
	int x=0,y=0,sum=0;
	cin >> n >> s;
	int len=s.size();
	s='0'+s;//为了更好处理开头是1的情况
	for(int i=0; i<s.size()-1; i++)
	{
		if(s[i]!=s[i+1]) sum++;
		if(s[i]=='1'||s[i+1]=='1') x++;
		if(s[i]=='0'||s[i+1]=='0') y++; 
	}
	if(!x)//全0
	{
		cout << len << endl;
		return ;
	}
	if(y==1)//全1
	{
		cout << len+1 << endl;
		return ;
	}
	if(sum==1)//(0)001原本就这样,1在最后
	{
		cout << len+1 << endl;
		return ;
	}
	if(sum==2)//(0)100或(0)010,变化两次,最后通过反转都变成(0)001
	{
		cout << len+1 <<endl;
		return ;
	}
	//一般情况,最少有3次变换(0)010010,通过反转可以减少两次变换:(0)000110
	cout << len+sum-2 << endl;
}

D. Tung Tung Sahur

来源:Problem - 2094D - Codeforces

难度:1100

这道div4的D题花了我40多分钟,wa了好多发··· 这可不像我的风格!如果不是题不算复杂我可能就放弃了。也是一道4月做过但没写对的题。题目非常好懂,有一发wa在没仔细看题。

思路

  • 将两字符串压缩并比较,看变化规律是否相同。例:LLLLRRLR->LRLR

  • 分别将连续相同字母串长度存起来,比较大小关系(a[i]<=b[i]&&a[i]*2>=b[i])。例:LLLLRRLR->{4,2,11}

  • 单独处理两串长度为1的情况

教训

  • 字符串特殊处理要处理彻底!(长度为1、2)
  • 容易出错的操作一定检查!(此题的a、b 数组)
  • 题目一定要仔细看!

代码

cpp 复制代码
void solve()
{
	cin >> x >> y;
	vector<int> a,b;
	string s1="",s2="";
	if(x.size()==1)//特殊处理
	{
		if(y.size()==1)
		{
			if(x==y) cout << "YES" << endl;
			else cout << "NO" << endl;
			return ;
		}
		if(y.size()>2||x[0]!=y[0]||x[0]!=y[1])
			cout << "NO" << endl;
		else cout << "YES" << endl;
		return ;
	}
	if(y.size()==1)
	{
		if(x.size()>2||x[0]!=y[0]||y[0]!=x[1])
			cout << "NO" << endl;
		else cout << "YES" << endl;
		return ;
	}
	int sum=-1;
	for(int i=0; i<x.size()-1; i++)//得到压缩字符串和长度数组
	{
		if(i==0) s1+=x[i];
		if(x[i]!=x[i+1])
		{
			s1+=x[i+1];
			a.push_back(i-sum);
			sum=i;
		}
	}
	a.push_back(x.size()-sum-1);//记得把最后那段加上!
	sum=-1;
	for(int i=0; i<y.size()-1; i++)
	{
		if(i==0) s2+=y[i];
		if(y[i]!=y[i+1])
		{
			s2+=y[i+1];
			b.push_back(i-sum);
			sum=i;
		}
	}
	b.push_back(y.size()-sum-1);
	if(s1!=s2||a.size()!=b.size())//变化规律必须一样
	{
		cout << "NO" << endl;
		return ;
	}
	for(int i=0; i<a.size(); i++)//两者存在数量关系
	{
		if(a[i]*2<b[i]||a[i]>b[i])
		{
			cout << "NO" << endl;
			return ;
		}
	}
	a.clear(),b.clear();//清理变量
}

B. Minimise Sum

来源:Problem - 2124B - Codeforces

难度:1000

思路

这题实现起来是真简单,就看能不能绕过来了。亏我想了大半天,还分好多种情况,这要是在比赛就慢了。

这题在同难度里竟然过的还算少的,看来也不完全是我的原因😁

  • 如果前两个数非递增,将a[2]加到a[1]上,对前两个数加不加都一样,但加上对后面是最优解
  • 如果前两个数递增,将a[3]加到a[2]上,a[3]之后都为0,前两个数都是a[1]

代码

cpp 复制代码
void solve()
{
	cin >> n;
	for(int i=1; i<=n; i++) cin >> a[i];
	if(a[1]>=a[2]) cout << a[1]+a[2] << endl;
	else cout << a[1]*2 << endl;
}

B. Shrinking Array

来源:Problem - 2112B - Codeforces

难度:1100

思路

这题也是边写边想,写的还算顺利,几分钟就过了

  • 如果原本就有相邻绝对值 < = 1 <=1 <=1的直接输出0
  • 此时再判断如果整个序列全部递增或递减输出 − 1 -1 −1
  • 否则(非单调)输出1

代码

cpp 复制代码
void solve()
{
	cin >> n;
	for(int i=1; i<=n; i++) cin >> a[i];
	for(int i=1; i<n; i++)//本来就有,无需操作
	{
		if(fabs(a[i]-a[i+1])<=1)
		{
			cout << 0 << endl;
			return ;
		}
	}
	int x=0,y=0;
	for(int i=1; i<n; i++)
	{
		if(a[i]>a[i+1]) x=1;
		if(a[i]<a[i+1]) y=1;  
	}
	if(!x||!y)//如果单调
	{
		cout << -1 << endl;
		return ;
	}
	cout << 1 << endl;//非单调通过一次操作是可以找到的
}

C1. Skibidus and Fanum Tax (easy version)

来源:Problem - 2065C1 - Codeforces

难度:1100

思路

这题看标签挺吓人的,其实还好,毕竟难度在这放着

  • 从第一个元素开始,逐个检查并决定是否替换当前元素
  • 若替换后的值(b-a [i])比原数小,且不小于前一个元素,就替换
  • 若原数已经比前一个元素小,必须替换,且替换后的值必须不小于前一个元素
  • 每处理一个元素后立刻看它是否不小于前一个元素。只要有一个不满足就不行

代码

cpp 复制代码
void solve()
{
    cin >> n >> m;
    for(int i=1; i<=n; i++) cin >> a[i];
    cin >> b;
    a[0]=INT_MIN;
    int f=1;
    for(int i=1;i<=n;i++)
    {
        if(b-a[i]<=a[i]&&b-a[i]>=a[i-1])
            a[i]=b-a[i];
        else if(b-a[i]>=a[i-1]&&a[i]<a[i-1]) 
            a[i]=b-a[i];
        if(a[i]<a[i-1])
        {
            f=0;
            break;
        }
    }
    if(!f) cout << "NO" << endl;
    else cout << "YES" << endl;
}

总结

整体的难度还行,写前两道题的时候有点麻烦,我想着这才1100的咋这么恶心。现在差不多就是这水平,再练练吧。

相关推荐
一枝小雨1 小时前
【数据结构】排序算法全解析
数据结构·算法·排序算法
略知java的景初1 小时前
深入解析十大经典排序算法原理与实现
数据结构·算法·排序算法
岁忧2 小时前
(LeetCode 每日一题) 498. 对角线遍历 (矩阵、模拟)
java·c++·算法·leetcode·矩阵·go
kyle~2 小时前
C/C++---前缀和(Prefix Sum)
c语言·c++·算法
liweiweili1262 小时前
main栈帧和func栈帧的关系
数据结构·算法
Greedy Alg3 小时前
LeetCode 560. 和为 K 的子数组
算法·leetcode·职场和发展
2501_924877213 小时前
强逆光干扰漏检率↓78%!陌讯多模态融合算法在光伏巡检的实战优化
大数据·人工智能·算法·计算机视觉·目标跟踪
2501_924877353 小时前
智慧零售漏扫率↓79%!陌讯多模态融合算法在智能收银与货架管理的实战解析
大数据·人工智能·算法·目标检测·边缘计算·零售
爱编程的鱼4 小时前
C# 数组&C# 多维数组
数据结构·算法·c#
前端开发工程师请求出战4 小时前
MCP — 让AI变得更“百搭”
算法