题目链接:点击查看

题目大意:七夕节因牛郎织女的传说而被扣上了「情人节」的帽子。于是TYVJ今年举办了一次线下七夕祭。Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去TYVJ七夕祭游玩。

TYVJ七夕祭和11区的夏祭的形式很像。矩形的祭典会场由N排M列共计N×M个摊点组成。虽然摊点种类繁多,不过cl只对其中的一部分摊点感兴趣,比如章鱼烧、苹果糖、棉花糖、射的屋……什么的。Vani预先联系了七夕祭的负责人zhq,希望能够通过恰当地布置会场,使得各行中cl感兴趣的摊点数一样多,并且各列中cl感兴趣的摊点数也一样多。

不过zhq告诉Vani,摊点已经随意布置完毕了,如果想满足cl的要求,唯一的调整方式就是交换两个相邻的摊点。两个摊点相邻,当且仅当他们处在同一行或者同一列的相邻位置上。由于zhq率领的TYVJ开发小组成功地扭曲了空间,每一行或每一列的第一个位置和最后一个位置也算作相邻。现在Vani想知道他的两个要求最多能满足多少个。在此前提下,至少需要交换多少次摊点。

题目分析:中文题目,题意不难理解,首先我们应该知道,行和列是两个独立的个体,在交换相邻两行的时候,对列是没有贡献的,同理,在交换相邻两列的时候,对行也是没有贡献的,所以我们只针对于交换相邻两列的情况讨论:

首先列数一共有m列,摊数一共有t个,若t%m不为0,那么对于列是无解的,如果有解的话,那么每一列最后都需要有t/m个摊点才行,而相邻两个可以交换,我们先假设当前的模型不是环状的而是线状的,a[1]是开头,a[m]是结尾,这样一来就能线性递推出答案了,比如:

  1. 若a[i]>t/m,则a[i]需要给a[i+1] a[i]-t/m个摊点
  2. 若a[i]<t/m,则a[i+1]需要给a[i] t/m-a[i]个摊点

用上面的关系就能线性递推出答案了

但实际上题目并不是这么简单的,题目将线性的模型改成了环状的模型,也就是说必定存在着一种最优解,能让答案最小,换句话说,必定有两个相邻的列之间没有发生摊位的交换,就像上面提到的线性模型一样,开头节点和末尾节点之间就没有发生摊位的交换,在这种情况下求最优解,我们最朴素的方法是枚举每一个断点,一共需要枚举n次,每次都需要进行O(n)的递推,才能计算出答案,从而维护出最小值,总的时间复杂度为n*n+m*m,这个题目给出的n和m都达到了1e5的级别,所以n*n肯定会超时的,我们需要想办法优化

我们可以一开始就让a[i]数组的每一项都减去t/m,最后结果为正说明需要往后面扔,为负说明需要从后面拿,这样我们维护一个前缀和sum[i],第i项对答案的贡献就是abs(sum[i])了,其实思想和上面的方法类似,只不过上面的思想相当于模拟整个过程,而这里的思想是将模型抽象出来,转换为数学公式而已了,比如第i个位置的贡献是a[i],先不管他的正负,我们都需要将a[i]先转移(拿走或提供)给a[i+1],然后再计算a[i+1]的贡献,随后再将a[i+1]的贡献转移给a[i+2],如此往复就是一个前缀和了,并且当前前缀和的最后一项一定等于0,即sum[m]=0

但上述转换只是换了种方法求每个位置对答案的贡献,实质上时间复杂度还是O(n),并没有起到优化的作用,所以我们需要继续转换,到这里我们发现对于求答案,也只能优化为O(n)了,实在是没有办法再优化了,那么我们就只能着手于优化另一个O(n),也就是枚举n个端点选出最小值的过程了

因为有了前缀和sum[i]的辅助,我们可以设置某个断点k,此时第k+1个点充当第一个点,第k个点充当最后一个点,这样我们将刚才求得的前缀和稍加转换:

第几项   前缀和

a[k+1]    sum[k+1]-sum[k]

a[k+2]    sum[k+2]-sum[k]

....

a[m]       sum[m]-sum[k]

a[1]        sum[1]+sum[m]-sum[k]

....

a[k]        sum[k]+sum[m]-sum[k]

这样我们在知道断点的下标后,就可以O(1)求出所需要的前缀和了,也就不需要每次再用O(m)重新维护前缀和了

因为我们在上面提到过,sum[m]=0,那么上面的每一项都可以总结为一个通项了,对于第i项,他的前缀和就是sum[i]-sum[k],那么当前位置对答案的贡献也就是abs(sum[i]-sum[k]),我们现在只要找到k,使得i=[1,m]的贡献和最小就可以了,上面我们最朴素的方法是暴力枚举,线性维护最小值,但被我们直接驳回了,我们通过观察以及总结可以得出结论,若想让上面的式子贡献和最小,让sum[k]选取sum数组的中位数即可,这样我们只需要对sum数组排序,时间复杂度为nlogn,忽略其余常数的话,这个题目的额时间复杂度就优化为nlogn+mlogm了,完美解决

不得不提一句,这个题目和“货仓选址”那个题目又有点不同,货仓选址那个题目也是让在数轴上选取一个位置,使得abs(a[i]-x)的贡献和最小,可以得出的结论是:

  1. 当n为奇数时,货仓建在a[n/2+1]处最优
  2. 若n为偶数时,货仓建在a[n/2]~a[n/2+1]之间(闭区间)的任何位置都是最优解

所以在做这个题目的时候,我直接按照分类讨论,当n为奇数时,求得的中位数是(a[n/2]~a[n/2+1])/2,但只得了90分,最后一拍脑瓜才知道,货仓选址这个题目的中位数是可以在数轴上任意选取的,但这个题目的中位数是只能再sum数组中选取,所以如果除以2的话,求出来的答案可能不是sum数组中的元素,所以求出来的答案就不满足题意了

那么对于这个题目,我们也无需分奇偶讨论了,统统以sum[(n+1)/2]作为中位数就可以了

还有一个细节需要注意,就是前缀和和最终答案可能会爆int,记得开longlong就好了

代码:

#include<iostream>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<climits>
#include<cmath>
#include<cctype>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<set>
#include<map>
#include<sstream>
using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e5+100;int n,m,t;LL ans_r,ans_c;struct Pos
{int x,y;
}a[N];LL c[N];bool solve_r()//处理行
{if(t%n)return false;memset(c,0,sizeof(c));for(int i=1;i<=t;i++)//记录每一列有多少个摊位c[a[i].x]++;for(int i=1;i<=n;i++)//维护前缀和c[i]=c[i]-t/n+c[i-1];sort(c+1,c+1+n);//排序LL temp=c[(n+1)/2];//中位数ans_r=0;for(int i=1;i<=n;i++)//计算贡献和ans_r+=llabs(c[i]-temp);return true;
}bool solve_c()//处理列,同上
{if(t%m)return false;memset(c,0,sizeof(c));for(int i=1;i<=t;i++)c[a[i].y]++;for(int i=1;i<=m;i++)c[i]=c[i]-t/m+c[i-1];sort(c+1,c+1+m);LL temp=c[(m+1)/2];ans_c=0;for(int i=1;i<=m;i++)ans_c+=llabs(c[i]-temp);return true;
}int main()
{
//  freopen("input.txt","r",stdin);
//  ios::sync_with_stdio(false);scanf("%d%d%d",&n,&m,&t);for(int i=1;i<=t;i++)scanf("%d%d",&a[i].x,&a[i].y);bool flag_c=solve_c();bool flag_r=solve_r();if(flag_c&&flag_r)printf("both %lld\n",ans_c+ans_r);else if(flag_c)printf("column %lld\n",ans_c);else if(flag_r)printf("row %lld\n",ans_r);elseprintf("impossible\n");return 0;
}

CH - 0502 七夕祭(思维+中位数优化+前缀和优化)相关推荐

  1. BZOJ3032 七夕祭 均分纸牌问题的变式 (前缀和+中位数)

    题目: 背景 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子.于是JoyOI今年举办了一次线下七夕祭.Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去JoyOI七夕祭游玩. 描述 ...

  2. acwing 105 七夕祭 中位数 + 前缀和 贪心

    七夕节因牛郎织女的传说而被扣上了「情人节」的帽子. 于是TYVJ今年举办了一次线下七夕祭. Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去TYVJ七夕祭游玩. TYVJ七夕祭和11 ...

  3. 中位数应用-货仓选址-纸牌均分-糖果传递-七夕祭

    1. 货仓选址 描述 在一条数轴上有N家商店,它们的坐标分别为 A[1]~A[N].现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品.为了提高效率,求把货仓建在何处,可以使得货 ...

  4. 中位数--《算法竞赛进阶指南》(货仓选址和七夕祭问题详解)

    中位数 今天又和大家见面了啦~ 依旧是 <算法竞赛进阶指南>的学习哦~ 中位数(Median)又称中值,统计学中的专有名词,是按顺序排列的一组数据中居于中间位置的数,代表一个样本.种群或概 ...

  5. AcWing 七夕祭

    AcWing 七夕祭 Description 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子. 于是TYVJ今年举办了一次线下七夕祭. Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决 ...

  6. 【NOIP2013模拟】七夕祭

    题目描述 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子.于是TYVJ今年举办了一次线下七夕祭.Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去TYVJ七夕祭游玩. TYVJ七夕祭 ...

  7. 七夕祭( Poetize系列)

    Description 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子.于是TYVJ今年举办了一次线下七夕祭.Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去TYVJ七夕祭游玩. ...

  8. 《算法竞赛进阶指南》0x05 T3 七夕祭

    题目描述 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子. 于是 TYVJ 今年举办了一次线下七夕祭. Vani 同学今年成功邀请到了 cl 同学陪他来共度七夕,于是他们决定去 TYVJ 七夕祭游玩 ...

  9. 【周末狂欢赛7】【NOIP模拟赛】七夕祭,齿轮(dfs),天才黑客

    文章目录 T1 题目 题解 code T2 题目 题解 code T3 题目 题解 code T1 题目 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子.于是TYVJ今年举办了一次线下七夕祭.Van ...

最新文章

  1. swoole UDP TCP客户端
  2. CephFS管理命令
  3. Windows 10 系统版本更新历史
  4. textarea标签内容为(英文或数字不自动换行)的解决方法
  5. 仿某某网站模板thinkphp_西安网站建设到底是什么?
  6. JavaScript条形码生成插件 - 封装篇
  7. bzoj 1070: [SCOI2007]修车【最小费用最大流】
  8. 机器学习-吴恩达-笔记-6-应用机器学习的建议
  9. Quartz的使用案例
  10. two sample ttest paired ttst
  11. R语言:KNN算法的实现——kknn包
  12. C#实现邮箱发送的多种方式
  13. 用服务器建立个人网站
  14. 图像增强及直方图均衡化在图像去雾上的应用(附matlab代码)
  15. 【node.js】nvm安装最新教程
  16. python学习笔记爬虫——爬取智联招聘信息
  17. sap进阶系列(16):第一篇:财务总览之全面预算管理
  18. uniapp打包h5_全局可视化装修商城上线,可打包APP
  19. node使用express+multer文件上传和下载的问题
  20. mysql jstorm_jstorm进阶-ack机制及KafkaSpout

热门文章

  1. MySQL高级 - 常用工具 - mysqladmin
  2. Nginx的server块和location块的简单说明
  3. Annotation 的前世今生
  4. 抽象工厂产品等级结构与产品族
  5. Lambda表达式的标准格式【理解】
  6. ES6新特性之Set和Map
  7. Eureka Server
  8. SpringBoot_入门-课程简介
  9. python制作软件封面_用python给MP3加封面图片,修改作者,专辑等信息
  10. OkHttp如何移除User-Agent,Accept-Encoding等框架自动添加的请求头参数