首页 > 其他分享 >洛谷题单指南-前缀和差分与离散化-P2882 [USACO07MAR] Face The Right Way G

洛谷题单指南-前缀和差分与离散化-P2882 [USACO07MAR] Face The Right Way G

时间:2024-08-01 12:17:53浏览次数:17  
标签:Right int 洛谷题 枚举 Face flag ansk ansm 翻转

原题链接:https://www.luogu.com.cn/problem/P2882

题意解读:一个有F、B组成的序列,每次可以翻转k个连续子序列,翻转:F->B,B->F,计算最少翻转多少次可以将序列都变成F,并求相应的k。

解题思路:

为方便处理,设F为1,B为0

1、朴素做法

枚举k:1~n

  枚举序列,一旦遇到0,就将连续k个字符翻转,如果可翻转的字符不足k个,则结束,这里也是贪心的思想,既然要全部变成F,当然遇到B就开始翻转会比较合理,这样已经处理过的位置就都变成F了,不用回头去处理。

时间复杂度:枚举k是n,枚举序列是n,将k个字符翻转是n,一共n^3,需要考虑优化

80分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 5005;
int a[N], b[N];
int n, ansk, ansm = INT_MAX;

int main()
{
    cin >> n;
    char c;
    for(int i = 1; i <= n; i++)
    {
        cin >> c;
        if(c == 'F') a[i] = 1;
        else if(c == 'B') a[i] = 0;
    }

    for(int k = 1; k <= n; k++)
    {
        memcpy(b, a, sizeof(a)); //把a拷贝一份
        int m = 0;
        for(int i = 1; i <= n; i++)
        {
            if(b[i] == 0)
            {
                int end = i + k - 1;
                if(end > n) break;
                //翻转操作
                for(int j = i; j <= end; j++)
                {
                    b[j] ^= 1; 
                }
                m++;
            }
            //如果i走到最后,且最后一个已经变为F
            if(i == n && b[i] == 1)
            {
                if(ansm > m)
                {
                    ansm = m;
                    ansk = k;
                }
            }
        } 
    }
    cout << ansk << " " << ansm;
    return 0;
}

2、差分优化

 TLE的关键在于翻转操作需要枚举k个元素,一个一个处理,但实际上,并不需要真的做翻转,只需要做一个标记:

bool flag=true表示从当前的i位置往后执行翻转,f[i + k]=true表示从i + k的位置执行翻转,因为做两次翻转等于不变,因此这样的效果就是标记了

从i到i-k+1范围执行翻转。

这样一来,在判断a[i]的数值时,可以结合flag来计算翻转之后的值。

要注意flag和f[]的几个更新点:

当要翻转时,flag = flag ^ 1,f[i + k] ^= 1

当遇到f[i]=true时,flag = flag ^ 1

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 5005;
int a[N], b[N];
int n, ansk, ansm = INT_MAX;

int main()
{
    cin >> n;
    char c;
    for(int i = 1; i <= n; i++)
    {
        cin >> c;
        if(c == 'F') a[i] = 1;
        else if(c == 'B') a[i] = 0;
    }

    for(int k = 1; k <= n; k++)
    {
        memcpy(b, a, sizeof(a)); //把a拷贝一份
        int m = 0;
        bool flag = false; //当前是否翻转
        bool f[N] = {false}; //f[i]=true表示从i之后是否翻转
        for(int i = 1; i <= n; i++)
        {
            if(f[i] == true) flag ^= 1; //当前状态改变
            if((b[i] ^ flag) == 0)
            {
                if(i + k - 1 > n) break;
                //翻转操作
                flag ^= 1; //当前状态基础上再翻转
                f[i + k] ^= 1; //i+k之后翻转
                m++; 
            }
            //如果i走到最后,且最后一个已经变为F
            if(i == n && (b[i] ^ flag) == 1)
            {
                if(ansm > m)
                {
                    ansm = m;
                    ansk = k;
                }
            }
        }
    }
    cout << ansk << " " << ansm;
    return 0;
}

 

标签:Right,int,洛谷题,枚举,Face,flag,ansk,ansm,翻转
From: https://www.cnblogs.com/jcwy/p/18336075

相关文章

  • 《最新出炉》系列初窥篇-Python+Playwright自动化测试-61 - 隐藏元素定位与操作
    1.简介 对于前端隐藏元素,一直是自动化定位元素的隐形杀手,让人防不胜防。脚本跑到隐藏元素时位置时报各种各样的错误,可是这种隐藏的下拉菜单又没有办法避免,所以非常头痛,这一篇只为交流隐藏元素自动化定位处理方法以及宏哥自己的一点浅薄见解。2.什么是隐藏元素隐藏元素,熟悉前端......
  • Python写UI自动化--playwright(点击操作)
    本篇介绍playwright点击操作,click()方法的常用参数目录0.selector(必需)1.modifiers(可选)2.position(可选)3.button(可选)4.click_count(可选)5.delay6.timeout(可选)7.force=True(可选)8.trial=True(可选)9.no_wait_after(可选)注意事项0.selecto......
  • 《最新出炉》系列初窥篇-Python+Playwright自动化测试-60 - 判断元素是否显示 - 下篇
    1.简介有些页面元素的生命周期如同流星一闪,昙花一现。我们也不知道这个元素在没在页面中出现过,为了捕获这一美好瞬间,让其成为永恒。我们就来判断元素是否显示出现过。在操作元素之前,可以先判断元素的状态。判断元素操作状态也可以用于断言。2.常用的元素判断方法2.1page对象调......
  • 洛谷题单指南-前缀和差分与离散化-P1083 [NOIP2012 提高组] 借教室
    原题链接:https://www.luogu.com.cn/problem/P1083题意解读:已知第i天有r[i]个教室可以供租借,有m个租借教室的订单,第i订单需要在第s[i]~t[i]天区间内租借d[i]个教室,计算是否全部订单都能满足,如果不满足要输出从第几个订单开始不满足。解题思路:1、朴素做法枚举1~m个订单,通过差分......
  • 洛谷题单指南-前缀和差分与离散化-P3406 海底高铁
    原题链接:https://www.luogu.com.cn/problem/P3406题意解读:1-n个城市共了n段路,第i段路不买卡票价a[i],买卡票价b[i](卡本身花费c[i]),给定一个路程顺序,计算最少的通行费用。解题思路:根据路程,计算每段路各走了多少次,然后对于每段路,计算买卡和不买卡两种花费,取较小的累加即可。如何......
  • go安装playwright-go
    写go调用Playwright时,遇到 couldnotstartPlaywright:pleaseinstallthedriver(v1.45.1)andbrowsersfirst:%!w(<nil>)报错解决方式:安装驱动和浏览器依赖。gorungithub.com/playwright-community/playwright-go/cmd/playwrightinstall--with-deps 测......
  • 洛谷题单指南-前缀和差分与离散化-P3017 [USACO11MAR] Brownie Slicing G
    原题链接:https://www.luogu.com.cn/problem/P3017题意解读:将一个r*c的矩阵,横向切成a条,每一条纵向切除b块,计算每一块子矩阵之和的最小值最大是多少。解题思路:要计算最小值中最大的,直觉上可以采用二分,下面来分析单调性:给定一个子矩阵块之和的值,值越小可以划分的条数、块数就越多......
  • 《最新出炉》系列初窥篇-Python+Playwright自动化测试-58 - 文件下载
    1.简介前边几篇文章讲解完如何上传文件,既然有上传,那么就可能会有下载文件。因此宏哥就接着讲解和分享一下:自动化测试下载文件。可能有的小伙伴或者童鞋们会觉得这不是很简单吗,还用你介绍和讲解啊,不说就是访问到下载页面,然后定位到要下载的文件的下载按钮后,点击按钮就可以了。其实......
  • 无法在 Llama Index 中加载 HuggingFace Embeddings llama3.1
    我有一个非常简单的代码,如下所示:fromllama_index.embeddings.huggingfaceimportHuggingFaceEmbeddingembed_model=HuggingFaceEmbedding(model_name="meta-llama/Meta-Llama-3-8B")我看到这个模型,meta-llama/Meta-Llama-3-8B,只有4.5GB,而我有16GBRAM,最多只使用20......
  • 洛谷题单指南-前缀和差分与离散化-P2004 领地选择
    原题链接:https://www.luogu.com.cn/problem/P2004题意解读:在一个n*m的矩阵中,找到边长为c的正方形,使得正方形范围内的数之和最大,输出正方形的左上角坐标。解题思路:二维前缀和的简单应用第一步:计算二维前缀和第二步:枚举边长为c的正方形左上角,计算正方形区域的数之和,更新答案第......