Educational Codeforces Round 85 (Rated for Div. 2) (D)

本文介绍了一种解决有向图中寻找字典序最小路径的问题算法,通过贪心策略,每次选择字典序最小的顶点进行遍历,最终形成完整的序列。文章详细解释了算法原理,并提供了一个具体的例子和实现代码,展示了如何在O(n)的时间复杂度内找到指定位置的顶点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:
给定一个有n个顶点的有向图,任何一个顶点u与其他任意一个顶点v间都有两条有向边(u,v)(v,u),找到一条按字典序排列的走完所有边的序列,输出序列里从L到R的序列。
题解:
贪心就可以了,每次选择可以走的路线中,字典序最小的顶点去走。下面以5个顶点为例说明。
第一步一定是顶点1,下面贪心就是顶点2,然后回到顶点1,顶点2已经走过了,走顶点3,以此类推,可以得到序列 1 2 1 3 1 4 1 5,此时与顶点1有关的边只有(5,1),这条边是最后走的。所以走顶点2,最后可以得到完整序列:1 2 1 3 1 4 1 5 2 3 2 4 2 5 3 4 3 5 4 5 1
观察可以发现,我们可以把序列排成下面的情形:
1 2 1 3 1 4 1 5
2 3 2 4 2 5
3 4 3 5
4 5
1
一共5层,这样可以在O(n)的时间里找到位于L位置的顶点,以此为起点输出序列直到位置R。
代码如下:

    #include <bits/stdc++.h>
    using namespace std;
    long long t,n,l,r;//这里用long long 是怕乘法计算溢出(会不会溢出我也不知道(笑哭))
    int main ()
    {
    	ios::sync_with_stdio(false);
    	cin.tie(0);
    	cout.tie(0);
    	cin>>t;
    	while (t--)
    	{
    		cin>>n>>l>>r;
    		if (l==(n*(n-1)+1))//位置为序列末端直接输出1就好了
    		{
    			cout<<'1'<<endl;
    			continue;
    		}
    		long long sum=0,w_place=l;//sum为位置的前缀和,w_place为当前位置
    		long long c_place;//记录层数位置
    		for (int i=1;i<n;i++)//找到L位置的层数与在当前层数的位置
    		{
    			sum+=(n-i)*2;
    			if (l<=sum)
    			{
    				c_place=i;
    				break;
    			}
    			w_place-=(n-i)*2;
    		}
    		long long answer;
    		for (int i=1;i<(r-l+2);i++)//输出序列
    		{
    			if (w_place%2)//不难发现奇数位置输出的顶点就是层数
    			{
    				if (c_place==n)//最后一层是例外
    				cout<<'1'<<' ';
    				else
    				cout<<c_place<<' ';
    				w_place++;
    			}
    			else
    			{
    				answer=w_place/2+c_place;//偶数位置顶点则满足该公式
    				cout<<answer<<' ';
    				if (answer==n)//顶点与n相等进入下一层
    				{
    					c_place++;
    					w_place=1;
    				}
    				else//不等的话位置+1就好了
    				{
    					w_place++;
    				}
    			}
    		}
    		cout<<endl;
    	}
    	return 0;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值