1. 程式人生 > >JZOJ 3382. 【NOIP2013模擬】七夕祭

JZOJ 3382. 【NOIP2013模擬】七夕祭

目錄:

題目:

分析:

首先,同一列中的交換隻會影響行,同一行中的交換隻會影響列。所以我們可以分開考慮行與列這兩個問題。我做題時有一個疑問——空間結構會不會影響交換呢?如果兩列中在同一行均有喜愛攤位,是不可以交換的。emmm,自己畫個圖就會發現我多慮了。
那若是隻考慮行(或列),我們自然而然聯想到環形均分紙牌模型——每行(或列)原始所含有的喜愛攤位數量為初值,相鄰兩個行(或列)可以互相給,要求給的攤次最少。進而,設個未知數,列個方程,利用絕對值不等式得出結論,就可以用中位數解決了
複雜度O(nlogn + mlogm)。

程式碼:

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
using namespace std;
inline LL read() {
    LL d=0,f=1;char s=getchar();
    while
(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();} return d*f; } int x[110000],y[110000],ne[110000]; int main() { int n=read(),m=read(),t=read(); if(t%n==0&&t%m==0) printf("both "); else if(t%n==0) printf("row "); else if(t%m
==0) printf("column "); else {printf("impossible ");return 0;} int a,b; for(int i=1;i<=t;i++) { a=read();b=read(); x[a]++;y[b]++; } int e,mid;long long ans=0; if(t%n==0) { e=t/n; for(int i=1;i<=n;i++) x[i]-=e; for(int i=1;i<=n;i++) ne[i]=ne[i-1]+x[i]; sort(ne+1,ne+1+n); mid=(n+1)/2; for(int i=1;i<=n;i++) ans+=(long long)abs(ne[i]-ne[mid]); } if(t%m==0) { memset(ne,0,sizeof(ne)); e=t/m; for(int i=1;i<=m;i++) y[i]-=e; for(int i=1;i<=m;i++) ne[i]=ne[i-1]+y[i]; sort(ne+1,ne+1+m); mid=(m+1)/2; for(int i=1;i<=m;i++) ans+=(long long)abs(ne[i]-ne[mid]); } printf("%lld",ans); return 0; }