Bzoj P3032 七夕祭___前缀和+思维

83 篇文章 0 订阅
30 篇文章 0 订阅

题目大意:

有个 NM N ∗ M 的矩形, cl c l T T 个感兴趣的摊点Xi,Yi,问如何移动使得各行中 cl c l 感兴趣的摊点数一样多,并且各列中 cl c l 感兴趣的摊点数也一样多。
每次移动能将左右相邻或者上下相邻的交换,头尾也算相邻。
问两个要求最多能满足多少个。在此前提下,至少需要交换多少次摊点。

1N,M100000 1 ≤ N , M ≤ 100000
0Tmin(NM,100000) 0 ≤ T ≤ m i n ( N M , 100000 )
1XiN1YiM 1 ≤ X i ≤ N , 1 ≤ Y i ≤ M

分析:

这里写图片描述

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define N 100005

using namespace std;

typedef long long ll;

ll a[N], b[N], s[N];
int n, m, T;

ll Get_num(ll *C, int tot) 
{
    for (int i = 1; i <= tot; i++) 
    {
         ll x = C[i] - T / tot;
         s[i] = s[i - 1] + x;
    }
    sort(s + 1, s + tot + 1);
    ll rp = 0, cp = s[(tot + 1) >> 1];
    for (int i = 1; i <= tot; i++) 
         rp += fabs(s[i] - cp);
    return rp;
}

int main()
{
    scanf("%d %d %d", &n, &m, &T);  
    for (int i = 1; i <= T; i++)
    {
           int x, y;
           scanf("%d %d", &x, &y);
           ++a[x]; ++b[y];
    }
    int ans = 0;
    if (T % n == 0) ans += Get_num(a, n);
    if (T % m == 0) ans += Get_num(b, m);
    if (T % n == 0 && T % m == 0) printf("both %lld\n", ans);
             else if (T % n == 0) printf("row %lld\n", ans);
             else if (T % m == 0) printf("column %lld\n", ans);
                             else printf("impossible\n");
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值