1 条题解

  • 0
    @ 2025-8-24 22:46:07

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Limie
    **

    搬运于2025-08-24 22:46:07,当前版本为作者最后更新于2023-08-24 19:30:41,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    前言

    此题大家都是通过打表的方法找出等差数列的规律,却没有一个人证明,故我用自己的方法给大家讲明白为什么是等差数列。


    观察结论

    可以发现,如果字符串的开头或结尾是 F F ,则所有可能的情况正好构成一个公差为 1 1 的等差数列,否则它们会构成一个公差为 2 2 的等差数列。

    那如何证明呢?

    (1)从简单开始

    假设一个最简单的情况:整个序列中有且仅有一个 F F

    1. F F 在开头:

    序列可表示为 F......

    不妨设第二位为 BB

    序列可表示为 FB......

    设后面的序列中的兴奋程度(或价值,下文中统一用兴奋程度)为 aa

    则总序列可能的兴奋程度为 aaa+1a+1

    1. FF 在中间

    FF 两边的字符相同,不妨设为 BB

    则序列为:......BFB.....

    设左边序列兴奋程度为 aa,右边为 bb

    则兴奋程度可能为:a+ba+ba+b+2a+b+2

    否则,序列为:.......BFE.....

    设左边序列兴奋程度为 aa,右边为 bb

    兴奋程度为:a+b+1a+b+1

    1. FF 在结尾:同第 11 种。
    总结结论:当 FF 在开头或结尾时,公差为 11,否则公差为 22

    (2)数学归纳法

    若有 (n1)(n-1)FF 时,若满足结论,则需证 nnFF 时也相等。

    若开头或结尾没有 FF,设原来的兴奋程度的可能值为 a,a+2,a+4,...,a+2ka,a+2,a+4,...,a+2k

    将开头或结尾替换成 FF,则可能值的变换同简单情况,可能值为:

    a,a+2,a+4,...,a+2k,a+1,a+3,...,a+2k+1a,a+2,a+4,...,a+2k,a+1,a+3,...,a+2k+1,即 a,a+1,a+2,a+3,...,a+2k+1a,a+1,a+2,a+3,...,a+2k+1 即公差为 11 的等差序列。

    将中间一个非 FF 的位置换成 FF,过程也差不多,读者自证不难。


    综上,结论正确,证毕!!!

    Code:

    #include<bits/stdc++.h>
    #define x first
    #define y second
    using namespace std;
    typedef unsigned long long ULL;
    typedef long long LL;
    typedef pair<int,int> PII;
    int n,d=2;
    string st;
    int l()
    {
    	int ans=0;
    	string t=st;
    	for(int i=1;i<n;i++)
    		if(t[i]=='F')
    			if(t[i-1]=='B')t[i]='E';else t[i]='B';
    		
    	for(int i=1;i<n;i++)ans+=(t[i-1]==t[i]);
    	return ans;
    }
    int r()
    {
    	int ans=0;
    	string t=st;
    	for(int i=1;i<n;i++)
    		if(t[i]=='F')t[i]=t[i-1];
    	
    	for(int i=1;i<n;i++)ans+=(t[i-1]==t[i]); 
    	return ans;
    }
    int main()
    {
    	int i;
    	cin>>n>>st;
    	if(st[0]=='F'||st[n-1]=='F')d=1;
    	if(st[0]!='F'){
    		int x=l(),y=r();
    		cout<<(y-x)/d+1<<endl;
    		for(i=x;i<=y;i+=d)cout<<i<<endl;
    		return 0;
    	}
    	st[0]='B';
    	int x=l(),y=r();
    	st[0]='E';
    	x=min(x,l());
    	y=max(y,r());
    	cout<<(y-x)/d+1<<endl;
    		for(i=x;i<=y;i+=d)cout<<i<<endl;
    }
    
    • 1

    信息

    ID
    8555
    时间
    2000ms
    内存
    256MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者