题目描述

N头牛排成一列1<=N<=5000。每头牛或者向前或者向后。为了让所有牛都 面向前方,农夫每次可以将K头连续的牛转向1<=K<=N,求操作的最少 次数M和对应的最小K。

简单题意:给你一个01串,每次可以对长度为K的区间进行异或,求异或的最少次数以及对应的K。

解析:

这是一道有毒的模拟,我做了一个下午加加减减鼓捣半天都快吐(秃)了。

看到题第一反应二分答案,不过仔细一想,K和M并不相关,答案不具备单调性,无法二分出解。

所以,这道题其实是个模拟。

一个显而易见的贪心:从左往右,遇到0就以它为起点的K个点做异或,显然是最优的,每个0都至少要被异或一次,如果线性异或的话可以保证每个0只被异或一次,否则一定不优。

于是枚举K找答案。直接暴力模拟复杂度达到\(O(n^3)\),80pnts,无法接受。

考虑一个类似差分的优化,对于某一为0的位置\(i\),假设当前使用的长度为\(X\),那么我们在这个0的位置\(i\)打个标记\(A\),再在位置\(i+X\)的位置打个标记\(B\),表示从\(A\)开始到\(B\)进行了一次异或。

思考如何去打这个标记(卡我一下午),直接差分肯定是不行的。我们可以讨论任意一个位置\(i\),看它前面有多少个\(A,B\)标记,发现位置\(i\)的异或次数正是该位置前面\(A\)的标记数量-\(B\)的标记数量(\(A\)的量一定大于\(B\),这点很好理解)。

于是代码实现我又卡了(我好蒻)。

换个思路。

思考直接用异或打标记,方便又好理解,搞一个数组去记录标记\(B\),\(A\)标记我们可以直接在枚举时实现。

考虑用一个类似指针的东西当作标记\(A\)(有点不同于前面的\(A\)),在数组种从左往右移动,初值为0,遇到不同的数就对1进行异或,表示从这个遇到的不同的数位置开始进行翻转(有点绕),直到遇到一个标记\(B\)再把它异或回去为止。值得注意的是,这里我们并不需要对原数组进行改变,实际上\(A\)标记已经帮我们实现了“对\(A\)到\(B\)这个区间进行异或”的目的了(想一想,为什么)。这个确实有点难以理解,毕竟我搞了一下午呢。

如果用之前那种打标记法我觉得比较难理解,毕竟异或比较贴近原题,虽然而者本质相同。

参考代码:

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define N 5010
using namespace std;
int n,a[N],sum[N],d[N];
int main()
{
scanf("%d",&n);
char c;
for(int i=1;i<=n;++i){getchar();c=getchar();(c=='B')?a[i]=0:a[i]=1;}
int cnt=0,ans=INF,pos;
for(int k=1;k<=n;++k){
int flag=0;cnt=0;
bool can=1;
memset(d,0,sizeof(d));
for(int i=1;i<=n;i++){
flag^=d[i];
if(!a[i]^flag){
if(i+k-1>n){can=0;break;}
flag^=1,d[i+k]^=1;cnt++;
}
}
if(can&&ans>cnt) ans=cnt,pos=k;
}
cout<<pos<<' '<<ans<<endl;
return 0;
}

P2882 [USACO07MAR]Face The Right Way [贪心+模拟]的更多相关文章

  1. 贪心+模拟 Codeforces Round #288 (Div. 2) C. Anya and Ghosts

    题目传送门 /* 贪心 + 模拟:首先,如果蜡烛的燃烧时间小于最少需要点燃的蜡烛数一定是-1(蜡烛是1秒点一支), num[g[i]]记录每个鬼访问时已点燃的蜡烛数,若不够,tmp为还需要的蜡烛数, ...

  2. bzoj1704 / P2882 [USACO07MAR]面对正确的方式Face The Right Way

    P2882 [USACO07MAR]面对正确的方式Face The Right Way $n<=5000$?枚举翻转长度,顺序模拟就ok了 对于每次翻转,我们可以利用差分的思想,再搞搞前缀和. ...

  3. 贪心+模拟 ZOJ 3829 Known Notation

    题目传送门 /* 题意:一串字符串,问要最少操作数使得成为合法的后缀表达式 贪心+模拟:数字个数 >= *个数+1 所以若数字少了先补上在前面,然后把不合法的*和最后的数字交换,记录次数 岛娘的 ...

  4. CodeForces ---596B--Wilbur and Array(贪心模拟)

    Wilbur and Array Time Limit: 2000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Su ...

  5. 洛谷P2882 [USACO07MAR]面对正确的方式Face The Right Way(贪心)

    题目描述 Farmer John has arranged his N (1 ≤ N ≤ 5,000) cows in a row and many of them are facing forwar ...

  6. UVA 10714 Ants 蚂蚁 贪心+模拟 水题

    题意:蚂蚁在木棍上爬,速度1cm/s,给出木棍长度和每只蚂蚁的位置,问蚂蚁全部下木棍的最长时间和最短时间. 模拟一下,发现其实灰常水的贪心... 不能直接求最大和最小的= =.只要求出每只蚂蚁都走长路 ...

  7. CodeForces 797C Minimal string:贪心+模拟

    题目链接:http://codeforces.com/problemset/problem/797/C 题意: 给你一个非空字符串s,空字符串t和u.有两种操作:(1)把s的首字符取出并添加到t的末尾 ...

  8. CodeForces - 730A 贪心+模拟

    贪心策略: 1.只有一个最大值,选着第二大的一起参加比赛减分. 2.有奇数个最大值,选择三个进行比赛. 3.偶数个最大值,选择两个进行比赛. 为什么不把最大值全部选择? 因为最多只能选五个,有可能选择 ...

  9. (贪心 模拟?) codeVs1098 均分纸牌

    题目描述 Description 有 N 堆纸牌,编号分别为 1,2,…, N.每堆上有若干张,但纸牌总数必为 N 的倍数.可以在任一堆上取若于张纸牌,然后移动. 移牌规则为:在编号为 1 堆上取的纸 ...

随机推荐

  1. 【嵌入式硬件Esp32】Ubuntu 1804下ESP32交叉编译环境搭建

    一.ESP32概述EPS32是乐鑫最新推出的集成2.4GWi-Fi和蓝牙双模的单芯片方案,采用台积电(TSMC)超低功耗的40nm工艺,拥有最佳的功耗性能.射频性能.稳定性.通用性和可靠性,适用于多种 ...

  2. WCF之Windows宿主(可安装成服务自动并启动)

    WCF之Windows宿主(可安装成服务自动并启动) 创建解决方案WCFServiceDemo 创建WCF服务库(类库或WCF服务库)WCFService  ,添加引用System.ServiceMo ...

  3. 为nologin用户开一个terminal

    昨天,我在设置zabbix-agent的时候,发现agent机器上的zabbix用户并不能读取某文件信息.我就想跳到zabbix用户,后来失败,发现在/etc/passwd中,zabbix被设置为 z ...

  4. [.Net Core] - Asp.Net Core 编译成功,发布失败之解决

    背景 Asp.Net Core 项目编译成功,发布失败. 错误 Assets file 'D:\……\obj\project.assets.json' doesn't have a target fo ...

  5. Quartz.Net—TriggerBuilder

    TriggerBuilder TriggerBuilder是一个建造者模式,链式建造.通过静态方法构建一个TriggerBuilder实例,然后再调用类方法Build()创建一个ITrigger的实现 ...

  6. AVL排序二叉树树

    AVL树第一部分,(插入) AVL树是一种自平衡二叉搜索树(BST),其中对于所有节点,左右子树的高度差不能超过1. 一个AVL树的示例 上面的树是AVL树,因为每个节点的左子树和右子树的高度之间的差 ...

  7. 『Python基础练习题』day04

    # 1.写代码,有如下列表,按照要求实现每一个功能 # li = ['Conan', 'Kidd', 'blame', 'jimmy', 'RachelMoore'] # 计算列表的长度并输出 # 列 ...

  8. Java定时任务工具详解之Timer篇

    Java定时任务调度工具详解 什么是定时任务调度? ◆ 基于给定的时间点,给定的时间间隔或者给定的执行次数自动执行的任务. 在Java中的定时调度工具? ◆ Timer       ◆Quartz T ...

  9. jquery easyui form表单一开始就自动启用验证了,修改为form提交的时候在开启验证

    <form method="post" action="<%=path %>" class="easyui-form" d ...

  10. (面试题)请用C语言实现在32位环境下,两个无符号长整数相加的函数,相加之和不能存储在64位变量中

    分析:长整数相加,将结果分为高位和低位部分,分别保存在两个32整数中. 比如:unsigned int a = 0xFFFFFFFF, unsigned int b = 0x1, 结果用unsigne ...