[zyh_helen‘s Construction RoundT1]荒谬题解
题目描述
给定 n,构造一张 n 个点的简单有向无环图,使得距离为 2 的点对的个数不少于 2n(n−1)−n⌈log2n⌉。
点对 (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⌈log2n⌉,你将获得该测试点的满分;若 ⌊2n−1⌋×⌈2n−1⌉≤x<2n(n−1)−n⌈log2n⌉,你将获得该测试点 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;
}

浙公网安备 33010602011771号