CCF NOI1055. 走廊 (C++)

80 篇文章 6 订阅

1055. 走廊

题目描述

有一个M行N列的教室座位中,有D对同学总爱凑在一起讲话。现老师要用走廊隔开他们。但只能在行之间加入K条走廊,在列中加入L条走廊,问加在哪里能使效果最佳。(一对爱讲话的同学只有左右相邻或上下相邻)。

输入

第一行,有5各用空格隔开的整数,分别是M,N,K,L,D(2<=N,M<=1000,0<=K<M,0<=L<N,D<=2000)。接下来D行,每行有4个用空格隔开的整数,第i行的4个整数Xi,Yi,Pi,Qi,表示坐在位置(Xi,Yi)与(Pi,Qi)的两个同学会交头接耳(输入保证他们前后相邻或者左右相邻)。输入数据保证最优方案的唯一性。

输出

共两行。第一行包含K个整数,a1a2……aK,表示第a1行和a1+1行之间、第a2行和第a2+1行之间、…、第aK行和第aK+1行之间要开辟通道,其中ai< ai+1,每两个整数之间用空格隔开(行尾没有空格)。第二行包含L个整数,b1b2……bk,表示第b1列和b1+1列之间、第b2列和第b2+1列之间、…、第bL列和第bL+1列之间要开辟通道,其中bi< bi+1,每两个整数之间用空格隔开(行尾没有空格)。若有多组答案,输出字典序最小的一组。

样例输入

4 5 1 2 3
4 2 4 3
2 3 3 3
2 5 2 4

样例输出

2
2 4

数据范围限制

C++代码

#include <iostream>
#include <cstring>
#include <vector>
#include <map>
#include <iterator>
#include <algorithm>
#include <cassert>

using namespace std;

//#define CPP_STL_MAP_VECTOR 

class WP
{
public:
    int weight; // weight
    int roc;    // row or column
};

const int MAX_M = 1000;
const int MAX_N = 1000; 
const int MAX_D = 2000;
const int MAX_L = MAX_N-1; // L < N
const int MAX_K = MAX_M-1; // K < M


#ifdef CPP_STL_MAP_VECTOR

vector<WP> all_row_corridors_vec;
vector<WP> all_col_corridors_vec;

map<int, int> all_row_corridors_mp;  
map<int, int> all_col_corridors_mp;

#else

WP all_row_corridors[MAX_L];  
WP all_col_corridors[MAX_K];

#endif

bool comp(const WP &wp1, const WP &wp2)
{
    if (wp1.weight == wp2.weight)
    {
        return wp1.roc < wp2.roc;  // sort ascending by roc        
    }
    else
    {
        return wp1.weight > wp2.weight;  // sort descending by weight
    }
}

int main()
{
    int M, N, K, L, D;
    cin >> M >> N >> K >> L >> D;

    assert(N>=2 && N <= MAX_N && N > L);
    assert(M>=2 && M <= MAX_M);
    assert(K>=0 && K < M);
    assert(L>=0 && L < N);
    assert(D>=0 && D <= MAX_D && D > L);

#ifndef CPP_STL_MAP_VECTOR 
    for(int row=1; row<=MAX_L; row++)
    {
        all_row_corridors[row-1].roc    = row;
        all_row_corridors[row-1].weight = 0;
    }

    for(int col=1; col<=MAX_K; col++)
    {
        all_col_corridors[col-1].roc    = col;
        all_col_corridors[col-1].weight = 0;
    }
#endif

    int Xi, Yi, Pi, Qi;
    int max_col = 0, max_row = 0;

    for (int row=1; row<=D; row++)
    {
        cin >> Xi >> Yi >> Pi >> Qi;
        
        // check each pair students, and
        // calculate the corresponding corridors' weight 
        if (Xi == Pi)
        {
#ifdef CPP_STL_MAP_VECTOR 
            all_col_corridors_mp[min(Yi, Qi)]++;
#else
            all_col_corridors[min(Yi, Qi) - 1].weight++;
            max_col = max(max_col, min(Yi, Qi));
#endif
        }
        else if (Yi == Qi)
        {
#ifdef CPP_STL_MAP_VECTOR
            all_row_corridors_mp[min(Xi, Pi)]++;
#else
            all_row_corridors[min(Xi, Pi) - 1].weight++;
            max_row = max(max_row, min(Xi, Pi));
#endif
        }
    }

#ifdef CPP_STL_MAP_VECTOR
    WP wp;
    map<int, int>::iterator curr;
    for (curr=all_col_corridors_mp.begin();curr!=all_col_corridors_mp.end();curr++)
    {
        wp.roc    = curr->first;
        wp.weight = curr->second;
        all_col_corridors_vec.push_back(wp);
    }

    for (curr=all_row_corridors_mp.begin();curr!=all_row_corridors_mp.end();curr++)
    {
        wp.roc    = curr->first;
        wp.weight = curr->second;
        all_row_corridors_vec.push_back(wp);      
    }

    sort(all_row_corridors_vec.begin(), all_row_corridors_vec.end(), comp);
    sort(all_col_corridors_vec.begin(), all_col_corridors_vec.end(), comp);
#else
    sort(all_row_corridors, all_row_corridors+max_row, comp);
    sort(all_col_corridors, all_col_corridors+max_col, comp);
#endif

    // sort and output corridor(s) between rows
    vector<int> output_corridors_between_rows;

    for(int row=1;row<=K; row++)
    {
#ifdef CPP_STL_MAP_VECTOR
        output_corridors_between_rows.push_back(all_row_corridors_vec[row-1].roc);
#else
        output_corridors_between_rows.push_back(all_row_corridors[row-1].roc);
#endif
    }

    sort(output_corridors_between_rows.begin(), output_corridors_between_rows.end());
    copy(output_corridors_between_rows.begin(), output_corridors_between_rows.end(), 
         ostream_iterator<int>(cout, " "));
    cout << endl;

    // sort and output corridor(s) between columns
    vector<int> output_corridors_between_cols;

    for(int col=1;col<=L; col++)
    {
#ifdef CPP_STL_MAP_VECTOR
        output_corridors_between_cols.push_back(all_col_corridors_vec[col-1].roc);
#else
        output_corridors_between_cols.push_back(all_col_corridors[col-1].roc);
#endif
    }

    sort(output_corridors_between_cols.begin(),output_corridors_between_cols.end());
    copy(output_corridors_between_cols.begin(),output_corridors_between_cols.end(), 
         ostream_iterator<int>(cout, " "));
    cout << endl;

    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值