中位数性质(环形均分纸牌)

水了一个环形均分纸牌的问题:

叫七夕祭:原题链接

这个题就是一个裸的环形均分纸牌问题

用到的性质每个数到中位数距离之和是最短的。

code:

#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
typedef long long ll;
//中位数性质:每个点到中位数距离之和一定是到任意点的距离之和的最小值
ll row[N],col[N];
ll srow[N],scol[N];
int main(){
    int n,m,t;
    cin>>n>>m>>t;
    int sum=t;
    for(int i=0;i<t;i++){
        int x,y;
        cin>>x>>y;
        row[x]++;
        col[y]++;
    }
    // cout<<t<<endl;
    if(sum%n!=0&&sum%m!=0){
        cout<<"impossible"<<endl;
        return 0;
    }
    if(sum%n==0&&sum%m!=0){
        srow[0]=0;
        int avg=sum/n;
        for(int i=1;i<=n;i++){
            srow[i]=srow[i-1]+row[i]-avg;
        }
        sort(srow+1,srow+n+1);
        int mid=(1+n)>>1;
        ll cnt=0;
        for(int i=1;i<=n;i++){
            cnt+=abs(srow[i]-srow[mid]);
        }
        cout<<"row ";
        cout<<cnt<<endl;
        return 0;
    }
    if(sum%n!=0&&sum%m==0){
        scol[0]=0;
        int avg=sum/m;
        for(int i=1;i<=m;i++){
            scol[i]=scol[i-1]+col[i]-avg;
        }
        sort(scol+1,scol+m+1);
        int mid=(1+m)>>1;
        ll cnt=0;
        for(int i=1;i<=m;i++){
            cnt+=abs(scol[i]-scol[mid]);
        }
        cout<<"column ";
        cout<<cnt<<endl;
        return 0;
    }
    int avg1=sum/n,avg2=sum/m;
    srow[0]=0;
    for(int i=1;i<=n;i++){
        srow[i]=srow[i-1]+row[i]-avg1;
    }
    sort(srow+1,srow+n+1);
    int mid=(1+n)>>1;
    ll cnt1=0;
    for(int i=1;i<=n;i++){
        cnt1+=abs(srow[i]-srow[mid]);
    }
    scol[0]=0;
    for(int i=1;i<=m;i++){
        scol[i]=scol[i-1]+col[i]-avg2;
    }
    sort(scol+1,scol+m+1);
    mid=(1+m)>>1;
    ll cnt2=0;
    for(int i=1;i<=m;i++){
        cnt2+=abs(scol[i]-scol[mid]);
    }
    cout<<"both ";
    cout<<cnt1+cnt2<<endl;
    return 0;
}

原文地址:https://www.cnblogs.com/kstranger/p/12420933.html

时间: 2024-08-29 03:20:23

中位数性质(环形均分纸牌)的相关文章

P2512 [HAOI2008]糖果传递 - 贪心+中位数【环形均分纸牌问题】

P2512 [HAOI2008]糖果传递 Sol: 环形均分纸牌问题 考虑最基本的均分纸牌问题,相当于将环从1与n之间断开. 令\(res_i\)表示第\(i\)个人达到平均值所用步数,ave$表示糖果的平均数. 则 \(res_1=a_1-ave\) \(res_2=a_2-ave+res_1=a_1+a_2+2*ave\) \(res_3=a_3-ave+res_2=a_1+a_2+a_3-3*ave\) \(\dots\) \(res_i=a_i-ave+res_{i-1}=\sum_{j

CODEVS 2485 七夕祭 - 贪心+中位数【环形均分纸牌问题】

CODEVS 2485 七夕祭 Sol: 当行的平均值不为整数时,不能均分,列同理. 对行和列分别做一次环形均分纸牌问题. AC CODE: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 100000 + 100; int read(){ int x=0,f=1;char ch=' '; while(ch>'9'||ch<'0

货仓选址模型与环形均分纸牌

目录 货仓选址模型 环形均分纸牌 货仓选址模型 可以如此描述:轴上有k个点,从轴上选择一点,使得此点到其他点的距离之和最小. 固定解:取k个点坐标的中位数 原因:取一点,异色于原先k个点,设此点正方向有p个与此点异色的点,负方向则有q个. 若将点向正方向移动,则距离之和减少p,增加q,反之减少q,增加p:当p.q不等时, 此点所在地必定不是最优解,按照更优方案改动此点的位置,直到p=q,最优解形成. 环形均分纸牌 经典均分纸牌的公式:\(sum(a[1],a[m])\). 环形均分纸牌的公式:\

环形均分纸牌的可链化处理证明

题目概括: 有N堆纸牌纸牌成环形.每次能够将一堆纸牌向相邻的另一堆转移一张,求最少转移多少次能够使每堆纸牌的数量一样多? 显然: 对于每一个连接处是单向传递的. 反证法: 若不成立,则传递示图定如下所示: 一. 此时,我们可以找出传递的值最小的一处的传递值 ,然后将每处都减小此值.显然是等效且更优的. 所以不可能存在这种情况. 二. 对于这种情况,我们可以发现都是有A传递至B,那么我们可以取消D的 其中一端的传递,由另一端完成,显然是可以做到的. 其他的情况都以此类推. 原文地址:https:/

[bzoj3032][TYVJ P1924]七夕祭(环形均分纸牌,货仓选址)

题意 七夕节因牛郎织女的传说而被扣上了「情人节」的帽子. 于是TYVJ今年举办了一次线下七夕祭. Vani同学今年成功邀请到了cl同学陪他来共度七夕,于是他们决定去TYVJ七夕祭游玩. TYVJ七夕祭和11区的夏祭的形式很像. 矩形的祭典会场由N排M列共计N×M个摊点组成. 虽然摊点种类繁多,不过cl只对其中的一部分摊点感兴趣,比如章鱼烧.苹果糖.棉花糖.射的屋--什么的. Vani预先联系了七夕祭的负责人zhq,希望能够通过恰当地布置会场,使得各行中cl感兴趣的摊点数一样多,并且各列中cl感兴

均分纸牌问题

这位大佬写的博客介绍的很详细,通俗易懂 https://blog.csdn.net/qq_38930523/article/details/89888915 自己敲了一遍代码... 线性均分纸牌: 1 #include<iostream> 2 #include<stdio.h> 3 using namespace std; 4 5 const int N=110; 6 int a[N],s[N]; 7 8 int main(){ 9 int n; 10 cin>>n;

Lydsy3032 七夕祭(货仓选址+均分纸牌结合)

环形均分纸牌 #include<cstdio> #include<cmath> #include<algorithm> using namespace std; typedef long long ll; const int maxn=100000+10; ll heng[maxn],shu[maxn]; ll sum[maxn]; ll getans(ll a[maxn],int n){ ll k=a[0]/n; for (int i=1;i<=n;i++){

洛谷P1368 均分纸牌(加强版)

P1368 均分纸牌(加强版) 题目描述 有 N 堆纸牌,编号分别为 1,2,…, N.每堆上有若干张,纸牌总数必为 N 的倍数.可以在任一堆上取1张纸牌,然后移动. 移牌规则为:在编号为 1 堆上取的纸牌,能移到编号为 2和N 的堆上:在编号为 N 的堆上取的纸牌,能移到编号为 N-1和1 的堆上:其他堆上取的纸牌,可以移到相邻左边或右边的堆上. 现在要求找出一种移动方法,使每堆上纸牌数都一样多且牌的移动次数尽量少. 输入输出格式 输入格式: 第一行一个整数n 第二行为n个空格分开的正整数,为

【算法学习笔记】25.贪心法 均分纸牌问题的分析

贪心法: 贪?算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解. 贪心算法不是对所有问题都能得到整体最优解,关键是贪?心策略的选择,选择的贪?策略必须具备?后效性,即某个状态以后的过程不会影响以前的状态,只与当前状态有关. 太概念化了.总结起来三点: 可行性:必须满足问题的约束 局部最优:当前步骤中所有可行的选择里最佳的局部选择. 不可取消:选择一旦做出,后面的步骤就无法改变. 问题要具有贪心选择性