[zyh_helen‘s Construction RoundT1]荒谬题解

题目描述

给定 n,构造一张 n 个点的简单有向无环图,使得距离为 2 的点对的个数不少于 2n(n−1)​−n⌈log2​n⌉。

点对 (u,v) 之间的距离指 u 到 v 的最短路长度。若 u 无法到达 v,则距离为 100100。

输入格式

一行一个正整数 n。

输出格式

第一行一个整数 m(0≤m≤2n(n−1)​),表示你构造的图的边数。

之后 m 行,每行两个数 u,v,表示你的构造的图中的一条边。你需要保证你构造的图是一张简单有向无环图,即没有重边也没有环。

输入输出样例

输入 #1复制

3

输出 #1复制

2
1 2
2 3

说明/提示

样例解释

样例中唯一距离为 2 的点对是 (1,3),容易证明不存在满足条件的点对个数比 1 大的方案。

数据范围

1≤n≤2000。

评分方式

若你的程序给出的图不为简单有向无环图,你该测试点的得分将为 0。

否则设你的程序给出的图中距离为 2 的点对数为 x。若 x≥2n(n−1)​−n⌈log2​n⌉,你将获得该测试点的满分;若 ⌊2n−1​⌋×⌈2n−1​⌉≤x<2n(n−1)​−n⌈log2​n⌉,你将获得该测试点 20% 的分数。

思路

首先,我们可以发现,可以让一点当中转点,两边的点相连,若平均,能有(n/2)*(n/2)的贡献,然后再重复操作即可。

代码见下

#include<bits/stdc++.h>
using namespace std;
long long n,m=0;
void abc(long long l,long long r){
    if(l>=r){
        return ;
    }
    long long mid=(l+r+1)/2;
    for(int i=l;i<=mid-1;i++){
        m++;
    }
    for(int i=mid+1;i<=r;i++){
        m++;
    }
    abc(l,mid-1);
    abc(mid+1,r);
    return ;
}
void abc2(long long l,long long r){
    if(l>=r){
        return ;
    }
    long long mid=(l+r+1)/2;
    for(int i=l;i<=mid-1;i++){
        cout<<i<<" "<<mid<<endl;
    }
    for(int i=mid+1;i<=r;i++){
        cout<<mid<<" "<<i<<endl;
    }
    abc2(l,mid-1);
    abc2(mid+1,r);
    return ;
}
int main(){
    cin>>n;
    abc(1,n);
    cout<<m<<endl;
    abc2(1,n);
	return 0;
}

posted @ 2025-10-04 19:10  bz02_2023f2  阅读(2)  评论(0)    收藏  举报  来源