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的咋这么恶心。现在差不多就是这水平,再练练吧。

相关推荐
设计师小聂!37 分钟前
力扣热题100------136.只出现一次的数字
数据结构·算法·leetcode
崎岖Qiu43 分钟前
leetcode643:子数组最大平均数 I(滑动窗口入门之定长滑动窗口)
java·算法·leetcode·力扣·双指针·滑动窗口
多思考少编码1 小时前
[GESP202309 四级] 2023年9月GESP C++四级上机题题解,附带讲解视频!
开发语言·c++·算法
TDengine (老段)2 小时前
TDengine IDMP 背后的技术三问:目录、标准与情景
大数据·数据库·物联网·算法·时序数据库·iot·tdengine
Crazy learner2 小时前
C语言fgets函数详解:安全读取字符串的利器
c语言·开发语言·算法
flashlight_hi2 小时前
LeetCode 分类刷题:2824. 统计和小于目标的下标对数目
javascript·数据结构·算法·leetcode
MicroTech20252 小时前
微算法科技(NASDAQ:MLGO)利用鸽群分散算法,提高区块链交易匹配算法效能
算法·区块链·量子计算
mochensage2 小时前
贪心算法
算法·信奥
HW-BASE2 小时前
C语言控制语句练习题1
c语言·开发语言·单片机·算法·嵌入式·c