AtCoder备赛冲刺必刷题(C++) | AtCoder AT_abc402_d Line Crossing

本文分享的必刷题目是从蓝桥云课洛谷AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。

欢迎大家订阅我的专栏:算法题解:C++与Python实现

附上汇总贴:算法竞赛备考冲刺必刷题(C++) | 汇总


【题目来源】

AtCoder:D - Line Crossing

【题目描述】

There are N N N equally spaced points on a circle labeled clockwise as 1 , 2 , … , N 1,2,…,N 1,2,,N.
圆上有 N N N 个等距的点,按顺时针方向依次标记为 1 , 2 , … , N 1, 2, …, N 1,2,,N

There are M M M distinct lines, where the i i i-th line passes through two distinct points A i A_i Ai and B i ( 1 ≤ i ≤ M ) B_i (1≤i≤M) Bi(1iM).
共有 M M M 条不同的直线,其中第 i i i 条直线穿过两个不同的点 A i A_i Ai B i ( 1 ≤ i ≤ M ) B_i (1≤i≤M) Bi(1iM)

Find the number of pairs ( i , j ) (i,j) (i,j) satisfying:
求满足以下条件的数对 ( i , j ) (i, j) (i,j) 的数量:

  • 1 ≤ i < j ≤ M 1≤i<j≤M 1i<jM, and
  • the i i i-th and j j j-th lines intersect.
    i i i 条直线与第 j j j 条直线相交。

【输入】

The input is given from Standard Input in the following format:

N M
A_1 B_1
A_2 B_2
.
.
.
A_M B_M

【输出】

Print the answer.

【输入样例】

8 3
1 5
1 8
2 4

【输出样例】

2

【代码详解】

#include <bits/stdc++.h>
using namespace std;
#define int long long  // 定义int为long long类型

int n, m, res1, res2;  // n: 模数, m: 点对数, res1/res2: 中间计算结果
int cnt[1000005];  // 计数数组,用于统计每个余数出现的次数

signed main()  // 使用signed代替int
{
    // 输入模数n和点对数m
    cin >> n >> m;
    
    // 处理每个点对
    for (int i = 1; i <= m; i++) {
        int x, y;  // 点对坐标
        cin >> x >> y;
        x = x - 1, y = y - 1;  // 坐标转换为0-based
        int t = (x + y) % n;   // 计算(x+y) mod n
        cnt[t]++;              // 统计该余数出现的次数(即平行边的数量)
    }
    
    // 计算所有可能的点对组合数C(m,2),即所有线对数量
    res1 = m * (m - 1) / 2;
    
    // 计算同余点对的组合数
    for (int i = 0; i < n; i++)
        if (cnt[i])  // 如果该余数出现过
            res2 += cnt[i] * (cnt[i] - 1) / 2;  // 计算该余数下点对的组合数,即平行边的数量
    
    // 输出结果:总组合数减去同余组合数
    cout << res1 - res2 << endl;
    
    return 0;
}

【运行结果】

8 3
1 5
1 8
2 4
2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值