脑洞题大概

首先处理出每个位置需要操作的次数c,假设第一次达到目标就不能再走,这样的操作次数是c差分后值的正数和,就想成分治每一段然后同减最小值然后从0处断开

然后考虑能一圈一圈走的情况,连续一段多走一圈在差分数组上的贡献是一个位置+4一个位置-4,

然后对于差分c后值为(-3,3)的一对位置,+4-4操作后变成(1,-1),对答案的贡献会-2;(-3,2),(-2,3)同理,对答案的贡献会-1

贪心的配对即可,先配(-3,3)的情况

#include<iostream>
#include<cstdio>
using namespace std;
const int N=10000005;
int n,a[N],b[N],c[N],s[N],top,s2,s3,ans;
bool v[N];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
int main()
{
n=read();
for(int i=1;i<=n;i++)
a[i]=read();
for(int i=1;i<=n;i++)
b[i]=read(),c[i]=(b[i]-a[i]+4)%4;
for(int i=n;i>=1;i--)
{
c[i]=c[i]-c[i-1];
if(c[i]>0)
ans+=c[i];
}
for(int i=1;i<=n;i++)
{
if(c[i]==-3)
s[++top]=i;
if(c[i]==3&&top)
{
ans-=2;
v[s[top--]]=1,v[i]=1;
}
}
for(int i=1;i<=n;i++)
if(!v[i])
{
if(c[i]==-3)
s3++;
if(c[i]==-2)
s2++;
if(c[i]==3&&s2)
ans--,s2--;
if(c[i]==2&&s3)
ans--,s3--;
}
printf("%d\n",ans);
return 0;
}

最新文章

  1. Visual Studio 默认保存为UTF8编码
  2. 【转载】LR提交JSON格式的请求
  3. [BZOJ1232][[Usaco2008Nov]安慰奶牛cheer(MST)
  4. Java 使用jaxp添加节点
  5. mongoDB 3.0.3 以上GUI 连接认证问题
  6. SGU 181.X-Sequence
  7. apacheOfbiz
  8. oracle备份、还原
  9. Java 数组扩容
  10. StackExchange.Redis 二次封装
  11. 20162318 实验三《 敏捷开发与XP实践》实验报告
  12. 从壹开始前后端分离 [ vue + .netcore 补程 ] 三十一║ Nuxt终篇:基于Vuex的权限验证探究
  13. ArcGIS 网络分析[2.5] VRP(车辆配送)【较难】
  14. Elasticsearch学习笔记三
  15. PPT领取 | 70+数据科学、架构演进等最佳实践限时放送
  16. MT【293】拐点处切线
  17. linux 记录所有用户bash操作日志
  18. ThinkPHP5调用PHPExcel类实现导入导出
  19. Android API 指南
  20. Shell数组遍历

热门文章

  1. Java类载入器(二)——自己定义类载入器
  2. SpringBoot学习之文件结构和配置文件
  3. Oracle创建索引的原则(转)
  4. Simple calculations
  5. Linux MySQL主从复制(Replication)配置
  6. 十天学习PHP之第二天
  7. js modify local file
  8. 使用zxing编写的二维码生成解析工具:QRCoder
  9. HDU3567 Eight II —— IDA*算法
  10. html5--6-52 动画效果-过渡