zoukankan      html  css  js  c++  java
  • AcWing 105 七夕祭 (贪心)

    题目链接:https://www.acwing.com/problem/content/107/

    我们发现:
    交换左右相邻的摊点,只会改变某两列的数量,同理,交换上下相邻的摊点有改变某两行的数量
    于是我们就可以将行和列分开考虑

    而对于行和列:就是经典的均分纸牌问题,不过这里是环形均分纸牌
    必然有一种最优解:有相邻两个位置不发生交换

    假设有(T)张牌,(N)个人,
    (A[i] = frac{T}{N}),(S[i])为前缀和
    从第(k)个人把环断开,(S[i]) 的变化是都减掉 (S[k])
    所以答案即为:$$sum_{i=1}^{N}mid S[i] - S[k] mid$$
    这就是货仓选址问题,把(S)排序,取中位数即为(S[k])的最优解

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    #include<stack>
    #include<queue>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 100010;
    
    int n, m, T; 
    int x[maxn] ,y[maxn], sum[maxn];
    
    ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
    
    int main(){
    	n = read(), m = read(), T = read();
    	
    	int X, Y;
    	for(int i=1;i<=T;++i){
    		X = read(), Y = read();
    		++x[X], ++y[Y];
    	}
    
    	int flagx = 0, flagy = 0;ll ansx = 0, ansy = 0;
    	
    	// 行 
    	if(T % n != 0) flagx = 1;
    	if(!flagx){
    		int num = T / n;
    		for(int i=1;i<=n;++i) x[i] -= num;
    		for(int i=1;i<=n;++i) sum[i] = sum[i-1] + x[i];
    		
    		sort(sum + 1, sum + 1 + n);
    		
    		int mid = sum[(n+1)/2];
    		for(int i=1;i<=n;++i) ansx += abs(sum[i] - mid);
    	} 
    	
    	memset(sum, 0, sizeof(sum));
    	// 列
    	if(T % m != 0) flagy = 1;
    	if(!flagy){
    		int num = T / m;
    		for(int i=1;i<=m;++i) y[i] -= num;
    		for(int i=1;i<=m;++i) sum[i] = sum[i-1] + y[i];
    
    		sort(sum + 1, sum + 1 + m);
    		
    		int mid = sum[(m+1)/2];
    		for(int i=1;i<=m;++i) ansy += abs(sum[i] - mid);
    	}  
    	
    	if(flagx && flagy) printf("impossible
    ");
    	else if(!flagx && flagy){
    		printf("row %lld
    ",ansx);
    	}else if(flagx && !flagy){
    		printf("column %lld
    ",ansy);
    	}else{
    		printf("both %lld
    ",ansx + ansy);
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    经典排序算法--快速排序
    经典排序算法——希尔排序
    经典排序算法——插入排序
    经典排序算法——选择排序
    经典排序算法——冒泡排序
    java递归求八皇后问题解法
    学习当前流行框架,同时也要自己去造建议的框架
    如何提高服务器并发处理能力
    数据的校验和空指针
    编写程序流程
  • 原文地址:https://www.cnblogs.com/tuchen/p/13928624.html
Copyright © 2011-2022 走看看