• 七夕祭


    问题描述

    七夕节因牛郎织女的传说而被扣上了「情人节」的帽子。于是 TYVJ 今年举办了一次线下七夕祭。Vani 同学今年成功邀请到了 cl 同学陪他来共度七夕,于是他们决定去 TYVJ 七夕祭游玩。
    TYVJ 七夕祭和 11 区的夏祭的形式很像。矩形的祭典会场由 N 排 M 列共计 N×M 个摊点组成。虽然摊点种类繁多,不过 cl 只对其中的一部分摊点感兴趣,比如章鱼烧、苹果糖、棉花糖、射的屋......什么的。Vani 预先联系了七夕祭的负责人 zhq,希望能够通过恰当地布置会场,使得各行中 cl 感兴趣的摊点数一样多,并且各列中 cl 感兴趣的摊点数也一样多。不过 zhq 告诉 Vani,摊点已经布置完毕了,唯一的调整方式就是交换两个相邻的摊点。两个摊点相邻,当且仅当他们处在同一行或者同一列的相邻位置上。由于 zhq 率领的 TYVJ 开发小组成功地扭曲了空间,每一行或每一列的第一个位置和最后一个位置也算作相邻。现在Vani 想知道他的两个要求最多能满足多少个。在此前提下,至少需要交换多少次摊点。

    输入格式

    第一行包含三个整数 N 和 M 和 T。T 表示 cl 对多少个摊点感兴趣。
    接下来 T 行,每行两个整数 x,y,表示 cl 对处在第 x 行第 y 列的摊点感兴趣。

    输出格式

    首先输出一个字符串。如果能满足 Vani 的全部两个要求,输出 both;如果通过调整 只能使得各行中 cl 感兴趣的摊点数一样多,输出 row;如果只能使各列中 cl 感兴趣的摊点数一样多,输出 column;如果均不能满足,输出 impossible。
    如果输出的字符串不是 impossible, 接下来输出最小交换次数,与字符串之间用一 个空格隔开。

    输入输出样例

    输入样例#1

    2 3 4
    1 3
    2 1
    2 2
    2 3

    输出样例#1

    row 1

    输入样例#2

    3 3 3
    1 3
    2 2
    2 3

    输出样例#2

    both 2

    数据说明

    对于 30% 的数据,N, M≤100。
    对于 70% 的数据,N, M≤1000。
    对于 100% 的数据,1≤N, M≤100000,0≤T≤min(NM, 100000),1≤x≤N,1≤y≤M。

    解析

    首先,我们能看出两点:

    • 使每一行或每一列摊点一样多,当且仅当摊点数能被行数或列数整除。
    • 行数量相等与列数量相等的操作互不影响。

    既然这样,那么我们可以首先判断是否可以在行或列上满足要求,然后分开考虑。以行为例,现在我们有(n)行,设第(i)行有(row[i])个摊点,那么目标就是使每一行都有(t/n) 个摊点(记为(ave))。设第(i)行给了第(i-1)(X_i)个摊点(若(X_i)为负数,那么就代表从第(i-1)个向第(i)个移动),那么总的答案(ans)就等于(sum_{i=1}^{n}{vert{X_i}vert})。对于第一行,原来有(row[1])个,给了第(n)(X_1)个,自己得到了(X_2)个,那么有如下关系:

    [row[1]-X_1+X_2=aveLongrightarrow X_2=X_1+(ave-row[1]) ]

    同理,其他的(X)也可以用(X_1)表示。由递推可得通项公式为:

    [X_i=X_1+i*ave-sum_{p=1}^{i-1}row[p] ]

    为方便表示,设(C_i=sum_{p=1}^{i-1}row[p]-ave*i),那么总答案可以表示为

    [ans=sum_{i=1}^{n}{vert{X_1-C_i}vert} ]

    考虑到绝对值的几何意义,答案可以看做是求数轴上的点(C_i)到定点(X_1)的距离之和的最小值。显然,当(X_i)位于序列(C)的中位数上时答案最小,统计答案即可。

    代码

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #define N 100002
    using namespace std;
    long long n,m,t,i,row[N],col[N],c[N];
    int main()
    {
    	freopen("tanabata.in","r",stdin);
    	freopen("tanabata.out","w",stdout);
    	cin>>n>>m>>t;
    	for(i=1;i<=t;i++){
    		int x,y;
    		cin>>x>>y;
    		row[x]++;col[y]++;
    	}
    	if(t%n==0&&t%m==0) cout<<"both ";
    	else if(t%n==0) cout<<"row ";
    	else if(t%m==0) cout<<"column ";
    	else{
    		cout<<"impossible"<<endl;
    		return 0;
    	}
    	long long ans=0;
    	if(t%n==0){
    		long long ave=t/n;
    		for(i=2;i<=n;i++) c[i]=c[i-1]+row[i]-ave;
    		sort(c+1,c+n+1);
    		int mid=c[(n+1)/2];
    		for(i=1;i<=n;i++) ans+=abs(c[i]-mid);
    	}
    	if(t%m==0){
    		long long ave=t/m;
    		for(i=2;i<=m;i++) c[i]=c[i-1]+col[i]-ave;
    		sort(c+1,c+m+1);
    		int mid=c[(m+1)/2];
    		for(i=1;i<=m;i++) ans+=abs(c[i]-mid);
    	}
    	cout<<ans<<endl;
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    
  • 相关阅读:
    关于 Delphi 中的Sender和易混淆的概念(转)
    C#实现打印与打印预览功能(转)
    Quartz.NET
    如何从Powerdesigner进行数据建模并生成SQL脚本
    pentaho BI套件中PSW和PDI的连接
    Oracle中如何使用imp语言导入dmp文件
    DatePicker和DateEdit的区别
    dev控件中LookUpEdit的数据绑定问题
    如何在GridControl的某一列放入CheckBox、Button以及其他控件
    在GridControl中如何选中某一行中的某一列
  • 原文地址:https://www.cnblogs.com/LSlzf/p/11003578.html
Copyright © 2020-2023  润新知