首页 > 试题广场 >

排座椅

[编程题]排座椅
  • 热度指数:3252 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 50M,其他语言100M
  • 算法知识视频讲解
\hspace{15pt}教室内共有 nm 列座位,坐在第 i 行第 j 列同学的位置记为 (i,j)

\hspace{15pt}为了方便进出,班主任计划设置 k横向通道(贯穿整列的水平通道)与 l纵向通道(贯穿整行的竖直通道)。通道位于相邻两行(或两列)之间。

\hspace{15pt}班主任记录了 d 对经常交头接耳的同学,他们的位置 (x_i,y_i)(p_i,q_i) 保证相邻(上下或左右)。她希望通过合理放置通道,使尽可能多的"交头接耳"对被通道隔开。

\hspace{15pt}现请你输出唯一的最优方案,在该方案下,仍未被通道隔开的"交头接耳"对的数量最少。

输入描述:
\hspace{15pt}第一行输入五个整数 n,m,k,l,d\left(2\leqq n,m\leqq 10^3;\ 0<k<n;\ 0<l<m;\ 0< d \leqq 2\times\min\{n\times m,2\times10^3\}\right)

\hspace{15pt}接下来 d 行,每行输入四个整数 x_i,y_i,p_i,q_i,表示坐标 (x_i,y_i)(p_i,q_i) 的两位同学会交头接耳,且两坐标上下相邻或左右相邻。

\hspace{15pt}保证最优方案存在且唯一。


输出描述:
\hspace{15pt}第一行输出 k 个严格递增的整数 a_1,a_2,\dots,a_k\left(1\leqq a_1<\dots<a_k\leqq n-1\right),在行 a_ia_i+1 之间设置横向通道。

\hspace{15pt}第二行输出 l 个严格递增的整数 b_1,b_2,\dots,b_l\left(1\leqq b_1<\dots<b_l\leqq m-1\right),在列 b_ib_i+1 之间设置纵向通道。
示例1

输入

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

输出

2
2 4

说明

\hspace{15pt}该样例如下图所示,蓝底斜线方格为第一对交头接耳的同学,绿底带叉方格为第二对交头接耳的同学,粉底带星方格为第三对交头接耳的同学。粗线代表通道。该划分方案为唯一最优方案。

示例2

输入

2 2 1 1 4
1 1 1 2
1 1 2 1
2 1 2 2
1 2 2 2

输出

1
1
我们将使用拉马努金瞪眼法解决这一题
注意到,其实横竖走廊其实不互相影响
一条的走廊不会影响任何一个的走廊,也不会影响任何一个着的走廊
也就是说,对于一条走廊来说,它应该被放置没有放置能切断最多的讲话学生的地方
最难点就是排序了吧,用 pair 就好了
注意到,代码要写成这样:
void solve()
{
    int n = q_, m = q_, k = q_, l = q_, d = q_;
    vector<pii>r(n + 1, { 0,0 }), c(m + 1, { 0,0 });
    ffp(i, 1, n)r[i].second = i;
    ffp(i, 1, m)c[i].second = i;
    ffp(i, 1, d)
    {
        int a = q_, b = q_, x = q_, y = q_;
        if (a == x) { c[min(b, y)].first++; }//同一行
        else { r[min(a, x)].first++; }//同一列
    }
    sort(r.begin(), r.end(), greater<pii>());
    sort(c.begin(), c.end(), greater<pii>());
    auto cmp = [&](pii a, pii b)->bool {return a.second < b.second; };
    sort(r.begin(), r.begin() +  k, cmp);
    sort(c.begin(), c.begin() +  l, cmp);
    ffp(i, 0, k - 1)cout << r[i].second << " \n"[i == k - 1];
    ffp(i, 0, l - 1)cout << c[i].second << " \n"[i == l - 1];
}

int main()
{
    int t = 1;
    while (t--)
    {
        solve();
    }

    return 0;
}


/*
⡀⠎⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣄⠃⠈⣶⡛⠿⠭⣉⠛⠿⡿⠛⠉⣀⣠⣤⣭⡏⠴⢀⣴⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠙⣿⣿
⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣷⣱⣬⠛⠉⠀⠀⢠⠀⠀⠀⢀⣀⠀⠉⠿⣿⣾⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠈⡿
⠀⠀⠀⠀⠀⠀⠀⢀⢿⣿⣿⣿⣿⣿⣿⠋⠀⠀⠀⠀⠀⡏⠀⠀⠀⠀⠈⠳⠀⠀⠀⠻⣿⣿⣿⣿⣿⣿⠋⠀⣇⠀⠀⠀⠀⠀⠀⠀⠀⠈
⠀⠀⠀⠀⠀⠀⠀⣸⠀⣿⣿⣿⣿⠟⠀⠀⠀⠂⠀⠀⢠⠀⠀⠀⠀⠀⠀⠀⠈⡀⠀⠀⠀⠻⣿⣿⣿⣿⣷⡀⠘
⠀⠀⠀⠀⠀⠀⠀⣧⣿⣿⣿⣿⠋⠀⠀⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠙⣿⣿⣿⣿⣿⣄⣧
⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⣾⠀⠀⠀⠀⠀⠀⠀⠀⠀⢧⠀⠀⠀⠀⠈⢿⣿⣿⣿⣿⣿⣆
⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⢂⠻⣿⣿⣿⣿⣿⣄
⠀⠀⠀⠀⠀⣿⣿⣿⣿⣹⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣇⠀⠀⠀⠀⠀⡄⠈⢿⣿⣿⣿⣿⣆
⠀⠀⠀⠀⣿⣿⣿⣿⠁⡇⠀⠀⠀⠀⠀⢸⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀⠐⠸⠀⠀⠻⣿⣿⣿⣆⢦
⠀⠀⢠⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⣼⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡏⣧⠀⠀⠀⠀⠐⣇⠀⠀⠙⣿⣿⣿⡄⠙⣄
⠀⣴⣿⣿⣿⣿⠏⠀⢸⠀⠀⠀⠀⠀⠀⡿⢿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣃⣈⣦⠀⠀⠀⠀⢹⠀⠀⠀⠸⣿⣿⣿⠀⠀⠳⣀
⠋⣸⣿⣿⣿⡟⠀⠀⠀⡆⠀⠀⠀⠀⠀⡏⠙⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢰⠀⢠⠀⠀⠀⢧⠀⠀⠀⠀⡇⠀⠀⠀⠘⣿⣿⣷⠀⠀⠘
⠀⣿⣿⣿⢩⠀⠀⠀⠀⣿⠀⠀⠀⠀⠀⣀⠀⢱⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠂⢀⣴⣶⣿⣿⡀⠀⠀⢻⠀⠀⠀⠀⠹⣿⣿⡄
⢸⣿⣿⠃⠈⠀⠀⢸⠀⣿⣆⠀⠀⠀⠀⣿⣿⣿⠷⠘⡀⠀⠀⠀⠀⠀⠀⢠⢹⡀⠈⡿⠻⣿⣛⢿⣿⣷⡀⠈⠀⠀⠀⠀⠀⢻⣿⣿
⣿⣿⣿⠀⠀⠀⠀⢸⠀⡇⣼⣄⠀⠀⠀⢻⣿⡄⠑⠑⣿⡀⠀⠀⠀⢀⠀⠂⠇⠀⠀⠖⠛⢿⣿⣿⣌⢿⣿⣿⡆⠀⠀⠀⠀⠀⣿⣿⡀
⣿⣿⡇⠀⠀⠀⠀⢸⠀⣾⣿⣿⡷⠿⣷⣤⣿⣿⡄⠀⠀⠀⠑⠤⡀⠀⠃⠀⠀⠀⠀⣿⣶⣿⣿⣿⣿⣆⠙⣿⣧⠀⠀⠀⠀⠀⣿⣿⡇
⣿⣿⠁⠀⠀⠀⠀⠘⣾⣿⣿⠁⣴⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠈⠀⠀⠀⠀⠀⠸⡏⠙⣿⠉⠻⣿⠀⠀⣿⠀⠀⠀⣄⠀⣿⢸⣷
⣿⣿⡇⠀⠀⠀⠀⠀⣿⣿⠁⠀⣿⣿⠋⣿⠏⠙⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⠀⢀⢻⠀⠀⢀⡟⢀⣿⣸⢃⠟
⣿⣿⣿⠀⡄⠀⠀⠀⠘⠻⡄⠀⢹⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡘⠀⢀⣿⠃⣿⣿⡗⠁
⣧⣿⣿⣧⢹⡀⠀⠀⠀⠱⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠀⣴⣿⣿⣾⣿⣿⣿
⢿⠘⣿⣿⣿⣿⣤⠀⠢⡀⠱⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣵⣿⣿⣿⣿⣿⣿⣿⣿⣷
⠀⠉⣿⣿⣿⡿⣿⠻⣷⣬⣓⣬⣄⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠉⠈⠈⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⠃⠼⢉⣿⣿⣿⣿⣿⣿⣿
⠀⠀⣿⣿⣿⣷⠀⠀⠀⠘⣿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⡏⠀⠀⢸⠀⢻⢿⣿⣿⡏⣿
⠀⢸⣿⣿⣿⣿⠀⠀⠀⠀⢻⣿⣿⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣴⣾⣿⣿⣿⣿⠀⠀⠀⢸⠀⠀⢸⣿⣿⠘⡀
⢦⡿⣿⣿⣿⢿⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣶⣶⣦⡄⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠘⡄⠀⠈⣿⣿⡄⠱
⣴⠛⣾⣿⣿⢸⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⡄⠀⠀⠀⠀⠀⠀⠀⣯⠛⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⣇⠀⠀⣿⣿⣿
⠿⠀⣿⣿⣿⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⠟⠰⡾⠃⠀⠀⠀⠀⠀⠀⠀⠙⡟⠀⢻⣿⣿⣿⣿⣿⡆⠀⠀⠀⠸⠀⠀⠸⣿⣿⣷
⠆⢳⣿⣿⡇⠀⠀⠀⠀⠀⠀⣿⣿⣿⠛⠿⠿⢿⡟⠀⠀⠉⠦⣀⡤⢶⠀⠖⠲⠶⠊⠀⠀⠀⢻⡛⠛⠛⣿⣿⠀⠀⠀⠀⠃⠀⠀⢿⣿⣿
*/



编辑于 2025-12-21 01:16:23 回复(1)
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(); // 行数
        int m = sc.nextInt(); // 列数
        int k = sc.nextInt(); // 横向通道数量
        int l = sc.nextInt(); // 纵向通道数量
        int d = sc.nextInt(); // 交头接耳的对数

        // 统计每个横向通道能隔开的对数
        int[] horizontal = new int[n];
        // 统计每个纵向通道能隔开的对数
        int[] vertical = new int[m];

        for (int i = 0; i < d; i++) {
            int x1 = sc.nextInt();
            int y1 = sc.nextInt();
            int x2 = sc.nextInt();
            int y2 = sc.nextInt();

            if (x1 == x2) {
                // 左右相邻,属于纵向通道
                int col = Math.min(y1, y2);
                vertical[col]++;
            } else {
                // 上下相邻,属于横向通道
                int row = Math.min(x1, x2);
                horizontal[row]++;
            }
        }

        // 选择最优的横向通道
        List<Integer> hList = new ArrayList<>();
        for (int i = 1; i < n; i++) {
            hList.add(i);
        }
        // 按重要性降序排序,重要性相同则按位置升序
        Collections.sort(hList, (a, b) -> {
            if (horizontal[a] != horizontal[b]) {
                return Integer.compare(horizontal[b], horizontal[a]);
            } else {
                return Integer.compare(a, b);
            }
        });
        // 取前k个并排序
        List<Integer> hResult = hList.subList(0, k);
        Collections.sort(hResult);

        // 选择最优的纵向通道
        List<Integer> vList = new ArrayList<>();
        for (int i = 1; i < m; i++) {
            vList.add(i);
        }
        // 按重要性降序排序,重要性相同则按位置升序
        Collections.sort(vList, (a, b) -> {
            if (vertical[a] != vertical[b]) {
                return Integer.compare(vertical[b], vertical[a]);
            } else {
                return Integer.compare(a, b);
            }
        });
        // 取前l个并排序
        List<Integer> vResult = vList.subList(0, l);
        Collections.sort(vResult);

        // 输出横向通道
        for (int i = 0; i < hResult.size(); i++) {
            if (i > 0) {
                System.out.print(" ");
            }
            System.out.print(hResult.get(i));
        }
        System.out.println();

        // 输出纵向通道
        for (int i = 0; i < vResult.size(); i++) {
            if (i > 0) {
                System.out.print(" ");
            }
            System.out.print(vResult.get(i));
        }
        System.out.println();
    }
}

发表于 2025-09-03 21:18:30 回复(0)

第一行输出 k 个严格递增的整数
第二行输出 l 个严格递增的整数

眼瞎仔,没有看见严格递增,😣
题意还是简单的,行列是无关的,单独考虑即可;对于每一个方向,统计每一个位置分开后能切断的对数数量,从大到小贪心选择即可

发表于 2025-12-21 15:31:16 回复(0)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

struct Interval {
    int pos;
    int count;
};

bool compare(const Interval& a, const Interval& b) {
    return a.count > b.count;
}

int main() {
    int n, m, k, l, d;
    cin >> n >> m >> k >> l >> d;

    vector<Interval> row_gaps(n - 1, {0, 0});
    vector<Interval> col_gaps(m - 1, {0, 0});

    for (int i = 0; i < d; ++i) {
        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        //统计使用某条通道的次数
        if (x1 == x2) {
            int col = min(y1, y2) - 1;
            col_gaps[col].count++;
            col_gaps[col].pos = col + 1;
        } else {
            int row = min(x1, x2) - 1;
            row_gaps[row].count++;
            row_gaps[row ].pos = row + 1;
        }
    }

    sort(row_gaps.begin(), row_gaps.end(), compare);
    sort(col_gaps.begin(), col_gaps.end(), compare);

    vector<int> selected_rows, selected_cols;
    //将使用最频繁的通道取出
    for (int i = 0; i < k; ++i) {
        selected_rows.push_back(row_gaps[i].pos);
    }
    for (int i = 0; i < l; ++i) {
        selected_cols.push_back(col_gaps[i].pos);
    }
    //保证结果从小到大输出
    sort(selected_rows.begin(), selected_rows.end());
    sort(selected_cols.begin(), selected_cols.end());

    for (size_t i = 0; i < selected_rows.size(); ++i) {
        if (i > 0) cout << " ";
        cout << selected_rows[i];
    }
    cout << endl;

    for (size_t i = 0; i < selected_cols.size(); ++i) {
        if (i > 0) cout << " ";
        cout << selected_cols[i];
    }
    cout << endl;

    return 0;
}
发表于 2025-07-09 15:31:16 回复(0)
对行列横竖分别考虑,因为不会相互影响,因为要最小化,所以考虑贪心,按每次设计走廊分隔的个数排序然后记录一下下标排序输出就可以了
struct R{
    int x;
    int id;
};
bool cmp(R a,R b){
    return a.x>b.x;
}
void solve(){
    int n,m,k,l,d;
    cin>>n>>m>>k>>l>>d;
    vector<R> s(m+1);
    vector<R> h(n+1);
    for(int i=1;i<=m;i++){
        s[i].x=0;
        s[i].id=i;
    }
    for(int i=1;i<=n;i++){
        h[i].x=0;
        h[i].id=i;
    }
    for(int i=1;i<=d;i++){
        int x1,y1,x2,y2;
        cin>>x1>>y1>>x2>>y2;
        if(x1==x2){
            s[min(y1,y2)].x++;
        }
        if(y1==y2){
            h[min(x1,x2)].x++;
        }
    }
    sort(h.begin(),h.end(),cmp);
    vector<int> ans;
    for(int i=0;i<k;i++){
        ans.push_back(h[i].id);
    }
    sort(ans.begin(),ans.end());
    for(int i=0;i<ans.size();i++){
        cout<<ans[i]<<" ";
    }
    ans.clear();
    cout<<'\n';
    sort(s.begin(),s.end(),cmp);
    for(int i=0;i<l;i++){
        ans.push_back(s[i].id);
    }
    sort(ans.begin(),ans.end());
    for(int i=0;i<ans.size();i++){
        cout<<ans[i]<<" ";
    }
}


发表于 2025-12-21 12:03:01 回复(0)
from collections import Counter
n,m,k,l,d=map(int,input().split())
list1=[]
list2=[]
for i in range(d):
    stu=list(map(int,input().split()))
    if stu[0]==stu[2]:
        list2.append(min(stu[1],stu[3]))
    else:
        list1.append(min(stu[0],stu[2]))
out1=sorted(Counter(list1).items(), key=lambda x: x[1], reverse=True)
out2=sorted(Counter(list2).items(), key=lambda x: x[1], reverse=True)
print(' '.join(map(str,sorted([i[0] for i in out1 if i[0]!=n][:k]))))
print(' '.join(map(str,sorted([i[0] for i in out2 if i[0]!=m][:l]))))
发表于 2025-11-18 14:44:13 回复(0)
#include <algorithm>
#include <iostream>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;

bool cmp1(pair<int, int> x, pair<int, int> y){
    if(x.second != y.second) return x.second > y.second;
    else return x.first < y.first;
}
bool cmp2(pair<int, int> x, pair<int, int> y){
    return x.first < y.first;
}
int main() {
    int n, m, k, l, d;
    int noise_r[1003] = {};
    int noise_c[1003] = {};
    cin >> n >> m >> k >> l >> d;
    while(d--){
        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;
        if(x1 == x2){
            noise_c[min(y1, y2)]++;
        }
        else{
            noise_r[min(x1, x2)]++;
        }
    }
    vector<pair<int, int> > _r;
    vector<pair<int, int> > _c;
    for(int i = 1; i <= 1000; i++){
        if(noise_r[i]) {
            _r.push_back({i, noise_r[i]});
            //cout << i << "  " << noise_r[i] << "        ";
        }
        if(noise_c[i]) {
            _c.push_back({i, noise_c[i]});
            //cout << i << " " << noise_r[i] << endl;
        }
    }
    sort(_r.begin(), _r.end(), cmp1);
    sort(_c.begin(), _c.end(), cmp1);
    sort(_r.begin(), _r.begin() + k, cmp2);
    sort(_c.begin(), _c.begin() + l, cmp2);
    for(int i = 0; i < k; i++){
        cout << _r[i].first << " ";
    }
    cout << endl;
    for(int i = 0; i < l; i++){
        cout << _c[i].first << " ";
    }
}

//此题颇有难度
发表于 2025-10-25 01:11:58 回复(0)
#include <stdio.h>
#include <stdlib.h>
//既然是贪心,那就找每一列和每一行的交头接耳的有多少对。优先选,某一行或者某一列交头接耳人数最多的给干掉就可以了,实现所谓的贪心。直到用完所有通道,好像也还行
//大佬的思路看来跟你想的一样

typedef struct
{
    int pos; //某一行或者某一列
    int count;  //记录这一行或者这一列上有多少对交投杰尔的同学
} hang_lie;

int compare(const void *p1,const void *p2)
{
    //如果相同应该按序号升序
    hang_lie temp1=(*(hang_lie*)p1);
    hang_lie temp2=(*(hang_lie*)p2);

    if(temp1.count<temp2.count)
    {
        return 1;
    }else if (temp1.count>temp2.count) {
        return -1;
    }else {
        //如果相同应该按序号升序
        if(temp1.pos<temp2.pos)
        {
            return -1;
        }else {
            return 1;
        }
    }

    return 0;//降序
}

int compare2(const void *p1,const void *p2)
{
    return (*(hang_lie*)p1).pos-(*(hang_lie*)p2).pos;//序号升序
}

int main() {

    int n, m,k,l,d;  //k行,l列
    scanf("%d %d %d %d %d",&n,&m,&k,&l,&d);
    
    //创建两个数组分别记录每行每列上有多少对交投杰尔的同学
    hang_lie* hang=malloc(sizeof(hang_lie)*n); //创建n行
    hang_lie* lie=malloc(sizeof(hang_lie)*m); //创建m列
    
    for (int i=0; i<n; i++) {  //初始化数值
        hang[i].pos=i+1;
        hang[i].count=0;
    }
    for (int i=0; i<m; i++) {
        lie[i].pos=i+1;
        lie[i].count=0;
    }

    //开始记录每行每列有多少对交头接耳同学
    for (int i=0; i<d; i++) {
        int x,y,p,q; 
        scanf("%d %d %d %d",&x,&y,&p,&q);

        //根据位置判断这两个同学是在行上还是列上交投接耳
        if (x==p) {   //如果纵坐标相同说明在行上交头
            lie[y<q?y-1:q-1].count++;//在这个列上记录一对 ,搞错了应该是用用小的那个列作为下标,而不是用x
        }else if (y==q){
            hang[x<p?x-1:p-1].count++;//在这个行上记录一对,应该是用小的另一个坐标那个作为下标
        }
    }

    //查看统计结果
    // printf("hang:\n");
    // for (int i=0; i<n; i++) {  //初始化数值
    //     printf("%d=%d \n",hang[i].pos,hang[i].count);
    // }
    // printf("列:\n");
    // for (int i=0; i<m; i++) {
    //     printf("%d=%d \n",lie[i].pos,lie[i].count);
    // }

    //排序后选最大的分割
    qsort(hang, n, sizeof(hang_lie), compare);
    qsort(lie, m, sizeof(hang_lie), compare);
    
    //行选前k个,列选前L个进行分割即可
    //还得按序号排序一次
    qsort(hang, k, sizeof(hang_lie), compare2);  //注意用的是compare2的排序
    qsort(lie, l, sizeof(hang_lie), compare2);
    
    for (int i=0; i<k; i++) {  //行选前k个,列选前L个输出即可
        printf("%d ",hang[i].pos);
    }
    printf("\n");
    for (int i=0; i<l; i++) {  //行选前k个,列选前L个输出即可
        printf("%d ",lie[i].pos);
    }

    return 0;
}

发表于 2025-10-10 17:25:01 回复(0)
from collections import Counter
row, col, r, c, d = map(int, input().split())
r_list = []
c_list = [] for i in range(d):
    ds = [int(x) for x in input().split()] if ds[0] == ds[2]:
        value = min(ds[1], ds[3])
        c_list.append(value) else:
        value = min(ds[0], ds[2])
        r_list.append(value)
count_r = sorted(Counter(r_list).items(), key=lambda items: items[1],reverse=True)
count_c = sorted(Counter(c_list).items(), key=lambda items: items[1],reverse=True) if len(set(r_list)) > r:
    result_r = [] for i in range(r):
        result_r.append(count_r[i][0])
    result_r = map(str, sorted(result_r)) print(' '.join(result_r)) else:
    result_r = map(str, sorted(set(r_list))) print(' '.join(result_r)) if len(set(c_list)) > c:
    result_c = [] for i in range(c):
        result_c.append(count_c[i][0])
    result_c = map(str, sorted(result_c)) print(' '.join(result_c)) else:
    result_c = map(str, sorted(set(c_list))) print(' '.join(result_c))
发表于 2025-10-04 10:47:33 回复(0)
代码怎么会这么复杂???
思路:尽量把过道修在能贯穿多个“交头接耳”同学行或列。
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void async function () {
    // Write your code here
    while(line = await readline()){
        const [n, m, k, l, d] = line.split(' ').map(Number);
        let sameRows = new Map();
        let sameCols = new Map();

        for (let i = 0; i < d; i++) {
            const [x, y, p, q] = (await readline()).split(' ').map(Number);
            if (x === p) {
                const k = Math.min(y, q);
                sameRows.set(k, (sameRows.get(k) || 0 ) + 1);
            } else {
                const k = Math.min(x, p)
                sameCols.set(k, (sameCols.get(k) || 0) + 1);
            }
        }

        let sameRowsArr = Array.from(sameRows);
        sameRowsArr.sort((a, b) => b[1] - a[1]);
        // console.log('sameRowsArr ', sameRowsArr)

        let sameColsArr = Array.from(sameCols);
        sameColsArr.sort((a, b) => b[1] - a[1]);
        // console.log('sameColsArr ', sameColsArr)
        
        const kList = [];
        for (let i = 0; i < sameColsArr.length; i++) {
            if (i < k) {
                kList.push(sameColsArr[i][0]);
            }
        }
        kList.sort((a, b) => a - b);

        const lList = [];
        for (let i = 0; i < sameRowsArr.length; i++) {
            if (i < l) {
                lList.push(sameRowsArr[i][0]);
            }
        }
        lList.sort((a, b) => a - b);

        console.log(kList.join(' '));
        console.log(lList.join(' '));
        
    }
}()

发表于 2025-09-27 17:29:20 回复(0)
n,m,k,l,d = map(int,input().split())
dic_heng = {}
dic_zong = {}
for i in range(d):
    x,y,p,q = map(int,input().split())
    if x==p:
        if min(y,q) not in dic_zong.keys():
            dic_zong[min(y,q)] = 1
        else:
            dic_zong[min(y,q)] += 1
    elif y==q:
        if min(x,p) not in dic_heng.keys():
            dic_heng[min(x,p)] = 1
        else:
            dic_heng[min(x,p)] += 1

list_heng = sorted(dic_heng,key=lambda x:-dic_heng[x])
list_zong = sorted(dic_zong,key=lambda x:-dic_zong[x])

print(' '.join(map(str,sorted(list_heng[0:k]))))
print(' '.join(map(str,sorted(list_zong[0:l]))))
发表于 2025-09-25 00:35:34 回复(0)
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int n,m,k,l,d;
    pair<int,int> x,y;
    cin>>n>>m>>k>>l>>d;
    vector<pair<int,int>> row(n-1);
    for(int i=0;i<n-1;i++){
        row[i].first=i+1;
        row[i].second=0;
    }
    vector<pair<int,int>> col(m-1);
    for(int i=0;i<m-1;i++){
        col[i].first=i+1;
        col[i].second=0;
    }
    for(int i=0;i<d;++i){
        cin>>x.first>>x.second>>y.first>>y.second;
        if(x.first==y.first)
        col[min(x.second,y.second)-1].second++;
        if(x.second==y.second)
        row[min(x.first,y.first)-1].second++;
    }
    sort(row.begin(),row.end(),[](auto const&a,auto const&b){return a.second>b.second;});
    sort(col.begin(),col.end(),[](auto const&a,auto const&b){return a.second>b.second;});
    sort(row.begin(),row.begin()+k,[](auto const&a,auto const&b){return a.first<b.first;});
    sort(col.begin(),col.begin()+l,[](auto const&a,auto const&b){return a.first<b.first;});
    for(int i=0;i<k;i++)
    cout<<row[i].first<<' ';
    cout<<'\n';
    for(int i=0;i<l;i++)
    cout<<col[i].first<<' ';
}

发表于 2025-09-20 12:07:04 回复(0)
//排序和后续处理上有点麻烦。
import java.util.*;
import java.io.*;
import java.util.stream.Collectors;

//横向只能分割上下相邻,纵向只能分割左右相邻
//遍历相邻同学对,统计横向或纵向的某条线各能隔开多少同学。
//选择符合题意的最多横向和纵向同学
public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        int[] line1 = Arrays.stream(bf.readLine().split(" ")).mapToInt(
                          Integer::parseInt).toArray();
        //分别统计行和列的整数
        TreeMap<Integer, Integer> tr = new TreeMap<>();
        TreeMap<Integer, Integer> tc = new TreeMap<>();

        for (int i = 1; i <= line1[4]; i++) {
            String[] pair = bf.readLine().split(" ");
            if (pair[1].equals(pair[3])) {
                int row = Math.min(Integer.parseInt(pair[0]), Integer.parseInt(pair[2]));
                tr.put(row, tr.getOrDefault(row, 0) + 1);
            } else {
                int col = Math.min(Integer.parseInt(pair[1]), Integer.parseInt(pair[3]));
                tc.put(col, tc.getOrDefault(col, 0) + 1);
            }
        }
        StringJoiner sj = new StringJoiner(" ");
        Map<Integer, Integer> Desc1 = tr.entrySet().stream()
                                      .sorted(Map.Entry.<Integer, Integer>comparingByValue().reversed()) // 降序排序
                                      .collect(Collectors.toMap(
                                              Map.Entry::getKey,
                                              Map.Entry::getValue,
                                              (e1, e2) -> e1, // 处理键冲突(此处无冲突)
                                              LinkedHashMap::new // 保持排序后的顺序
                                               ));
        int i = 0, j = 0;
        //收集到sj中进行然后再次用比较器排序
        for (Map.Entry<Integer, Integer> entry : Desc1.entrySet()) {
            if (i < line1[2]) {
                sj.add(entry.getKey().toString());
            } else {
                break;
            }
            i++;
        }
        String[] res = sj.toString().split(" ");
        Arrays.sort(res,(a,b)->Integer.parseInt(a)-Integer.parseInt(b));
        System.out.println(String.join(" ", res));
        Map<Integer, Integer> Desc2 = tc.entrySet().stream()
                                      .sorted(Map.Entry.<Integer, Integer>comparingByValue().reversed()) // 降序排序
                                      .collect(Collectors.toMap(
                                              Map.Entry::getKey,
                                              Map.Entry::getValue,
                                              (e1, e2) -> e1, // 处理键冲突(此处无冲突)
                                              LinkedHashMap::new // 保持排序后的顺序
                                               ));
        sj = new StringJoiner(" ");
        for (Map.Entry<Integer, Integer> entry : Desc2.entrySet()) {
            if (j < line1[3]) {
                sj.add(entry.getKey().toString());
            } else {
                break;
            }
            j++;
        }
        res = sj.toString().split(" ");
        Arrays.sort(res,(a,b)->Integer.parseInt(a)-Integer.parseInt(b));
        System.out.println(String.join(" ", res));
    }
}

发表于 2025-09-08 17:44:04 回复(0)
n, m, k, l, d = map(int, input().split())

# 记录每个可能的通道位置能阻断的"交头接耳"对数
row_blocks = [0] * (n - 1)  # 横向通道(在第i行和i+1行之间)
col_blocks = [0] * (m - 1)  # 纵向通道(在第j列和j+1列之间)

# 处理每对交头接耳的同学
for _ in range(d):
    x, y, p, q = map(int, input().split())

    # 如果是上下相邻的同学
    if y == q:
        # 通道应该放在min(x,p)和max(x,p)之间
        row_idx = min(x, p) - 1
        row_blocks[row_idx] += 1

    # 如果是左右相邻的同学
    elif x == p:
        # 通道应该放在min(y,q)和max(y,q)之间
        col_idx = min(y, q) - 1
        col_blocks[col_idx] += 1

# 创建(位置,阻断数)的元组列表并排序
row_pairs = [(i + 1, blocks) for i, blocks in enumerate(row_blocks)]
col_pairs = [(i + 1, blocks) for i, blocks in enumerate(col_blocks)]

# 按阻断数降序排序
row_pairs.sort(key=lambda x: x[1], reverse=True)
col_pairs.sort(key=lambda x: x[1], reverse=True)

# 选择前k个横向通道和前l个纵向通道
row_positions = [pos for pos, _ in row_pairs[:k]]
col_positions = [pos for pos, _ in col_pairs[:l]]

# 按位置升序排序输出
row_positions.sort()
col_positions.sort()

print(*row_positions)
print(*col_positions)

发表于 2025-08-25 14:41:11 回复(0)
有人会吗
发表于 2025-06-23 14:35:20 回复(0)