首页 > 其他分享 >构造题大赏

构造题大赏

时间:2024-07-06 16:09:15浏览次数:12  
标签:题大赏 typedef int long 构造 2n getchar define

T1

题目描述

是否存在 \(3\) 个长度为 \(n\) 的 \([0,n)\) 的排列 \(a,b,c\),使得 \(a_i+b_i=c_i \mod n\)。如果没有输出 -1,否则输出构造方案。

题解

如果 \(n\) 为奇数,不妨让 \(a,b\) 都是 \(0,1,2,3,\cdots\) 的排列即可。那么 \(c\) 一定也是一个排列

如果 \(n\) 为偶数,那么 \(a,b\) 所有数的和为 \(n(n-1)=0 \mod n\),但是 \(c\) 的和为 \(\frac{n(n-1)}{2}=\frac{n}{2} \mod n\),无解

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;
//# define int long long
# define rd(t) read <t> ()
# define mem(a, b) memset (a, b, sizeof (a))
# define fi first
# define se second
# define lc u << 1
# define rc u << 1 | 1
# define debug printf ("debug\n")
const int N = 100005; 
template <typename T> inline T read ()
{
    T s = 0; int w = 1; char c = getchar (); 
    for (; !isdigit (c); c = getchar ()) { if (c == '-') w = -1; }
    for (; isdigit (c); c = getchar ()) s = (s << 1) + (s << 3) + c - '0';
    return s * w;
}

int n; 
signed main ()
{
	n = rd (int); 
	if (n % 2 == 0) { printf ("NO\n"); return 0; }
	printf ("YES\n"); 
	for (int i = 0; i < n; i ++ ) printf ("%d ", i); printf ("\n"); 
	for (int i = 0; i < n; i ++ ) printf ("%d ", i); printf ("\n"); 
	for (int i = 0; i < n; i ++ ) printf ("%d ", 2 * i % n); printf ("\n"); 
	return 0;
}

T2

题目描述

给定一张 \(2^n-1\) 个点的完全图,你需要找出尽量多边互不相交的三元环,输出最优情况下的方案 。(这里的边互不相交不是平面上的相交,是没有两个三元环拥有同一条边)

题解

从构造的角度来思考:如果能构造出的答案达到上界,那么它一定是最优解
先把答案的上界算出来:\(\frac{(2^n-1)(2^n-2)}{6}\)。因为连续 \(3\) 个数中一定有一个是 \(3\) 的倍数,所以答案的上界是整数。

我们可以把点从 \(1\) 到 \(2^n-1\) 编号,把满足 \(x \oplus y \oplus z=0\) 的 \((x,y,z)\) 当做三元环。这种构造可以取到上界。

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;
//# define int long long
# define rd(t) read <t> ()
# define mem(a, b) memset (a, b, sizeof (a))
# define fi first
# define se second
# define lc u << 1
# define rc u << 1 | 1
# define debug printf ("debug\n")

template <typename T> inline T read ()
{
    T s = 0; int w = 1; char c = getchar (); 
    for (; !isdigit (c); c = getchar ()) { if (c == '-') w = -1; }
    for (; isdigit (c); c = getchar ()) s = (s << 1) + (s << 3) + c - '0';
    return s * w;
}

int n; 
signed main ()
{
	n = rd (int); 
	n = pow (2, n) - 1; 
	int m = n * (n - 1) / 6; 
	printf ("%d\n", m); 
	for (int i = 1; i <= n; i ++ )
	{
		for (int j = i + 1; j <= n; j ++ )
		{
			int k = 0 ^ i ^ j; 
			if (k > j) printf ("%d %d %d\n", i, j, k); 
		}
	}
    return 0;
}

T3

题目描述

给定一个 \(2n\) 个点的完全图,要把这些边分成 \(2n-1\) 组,每组 \(n\) 条边,且每条都是一个匹配(任意两条边没有公共点)

题解

把所有的点从 \(0\) 到 \(2n-1\) 编号。我们可以把 \(0\) 到 \(2n - 2\) 和 \(2n-1\) 分开考虑。

对于一组边 \((x,y)\) 满足 \(0\leq x < y < 2n-1\),我们把他们扔到 \((x+y)\mod (2n-1)\) 这一组。
因为 \(2n-1\) 是奇数,所以每个 \(i\) 有且只有一个 \(k\) 使得 \(2k=i \mod 2n-1\)。所以把 \((k,2n-1)\) 这条边扔到 \(i\) 这一组里就行

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;
//# define int long long
# define rd(t) read <t> ()
# define mem(a, b) memset (a, b, sizeof (a))
# define fi first
# define se second
# define lc u << 1
# define rc u << 1 | 1
# define debug printf ("debug\n")
const int N = 2005; 
template <typename T> inline T read ()
{
    T s = 0; int w = 1; char c = getchar (); 
    for (; !isdigit (c); c = getchar ()) { if (c == '-') w = -1; }
    for (; isdigit (c); c = getchar ()) s = (s << 1) + (s << 3) + c - '0';
    return s * w;
}

int n; 
vector <pii> vec[N]; 
signed main ()
{
	n = rd (int); 
	for (int i = 0; i < 2 * n - 1; i ++ )
	{
		for (int j = i + 1; j < 2 * n - 1; j ++ )
			vec[(i + j) % (2 * n - 1)].push_back ({i, j}); 
	}
	for (int i = 0; i < 2 * n - 1; i ++ )
	{
		for (int k = 0; k < 2 * n - 1; k ++ )
		{
			if ((2 * k) % (2 * n - 1) == i)
				vec[i].push_back ({k, 2 * n - 1}); 
		}
	}
	// return 0; 
	for (int i = 0; i < 2 * n - 1; i ++ )
	{
		// cout << i << endl; 
		for (auto t : vec[i]) printf ("%d %d\n", t.fi + 1, t.se + 1); 
		printf ("\n"); 
	}
    return 0;
}

T4

题目描述

求将 \(n\) 个点的完全图划分成最多的生成树的数量,并输出一种构造方案

题解

一棵生成树有 \(n-1\) 条边,而原完全图只有 \(\frac{n(n-1)}{2}\) 条边,所以最多的生成树数量为 \(\left \lceil \frac{n}{2} \right \rceil\)

我们只需要考虑 \(n\) 为偶数的情况,因为 \(n\) 为奇数时可以从 \(n-1\) 的个点的构造方案中继承过来

假设最新加入的点是 \(i-1\),\(i\)
首先,对 \(i-1\) 和 \(i\) 建一颗新树,连边方式如下:

  • \(n-1 \to n\)
  • 对于 \(1\) ~ \(n-2\):奇数连 \(n\),偶数连 \(n-1\)

还需要再之前的树上连上 \(n-1\) 和 \(n\)。对于之前的点:奇数连 \(n-1\),偶数连 \(n\)。

# include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair <int, int> pii;
//# define int long long
# define rd(t) read <t> ()
# define mem(a, b) memset (a, b, sizeof (a))
# define fi first
# define se second
# define lc u << 1
# define rc u << 1 | 1
# define debug printf ("debug\n")
const int N = 2005; 
template <typename T> inline T read ()
{
    T s = 0; int w = 1; char c = getchar (); 
    for (; !isdigit (c); c = getchar ()) { if (c == '-') w = -1; }
    for (; isdigit (c); c = getchar ()) s = (s << 1) + (s << 3) + c - '0';
    return s * w;
}

int n; 
struct node { int u, v; }; 
vector <node> tr[N]; 
signed main ()
{
	n = rd (int); 
	printf ("%d\n", n / 2); 
	if (n % 2 == 1)
	{					
		for (int i = 1; i <= n / 2; i ++ )
			tr[i].push_back ({i * 2, n}); 
	}
	for (int u = 2; u <= n; u += 2)
	{
		int v = u - 1; 
		tr[u / 2].push_back ({u, v}); 
		for (int i = 2; i < u; i += 2)
		{
			int j = i - 1; 
			tr[u / 2].push_back ({i, v}); tr[u / 2].push_back ({j, u}); 
			tr[i / 2].push_back ({i, u}); tr[i / 2].push_back ({j, v}); 
        }
    }
    for (int i = 1; i <= n / 2; i ++ )
    {
    	for (int j = 0; j < tr[i].size (); j ++ )
    		printf ("%d %d ", tr[i][j].u, tr[i][j].v); 
    	printf ("\n"); 
	}
    return 0;
}

标签:题大赏,typedef,int,long,构造,2n,getchar,define
From: https://www.cnblogs.com/legendcn/p/18287359

相关文章

  • 20240705总结(欧拉回路,构造)
    A-FairShareCF1634EFairShare题解:用二分图做的。首先如果一种颜色出现奇数次一定无解。否则对于一种颜色的点分组,每组两个之间连边,保证每种颜色平分。然后把每一个数组分成n[i]/2组,每组两个之间连边,保证每一个数组平分。这样一定连出的是二分图,黑白染色B-NecklaceCF......
  • DCS292 编译器构造实验,手工编写递归下降预测分析程序(2.3)
    help-assignment2.4实验四、手工编写递归下降预测分析程序实验四要求你利用Java语言手工编写一个Oberon-0语言的语法分析程序,该语法分析程序执行与实验三自动生成的语法分析程序类似的功能,但实验三要求逆向工程工具生成的是调用图,而实验四要求生成的是流程图(Flowch......
  • DCS292 编译器构造实验,实验三
    help-assignmentDCS292编译器构造实验,实验三3Oberon-0语言本实验的处理对象是Oberon-0语言,该语言中包含了高级程序设计语言的表达式,以及结构化程序设计中的结构化控制结构、子程序、参数传递等机制的抽象。3.1简介用于编译原理实验的计算机语言应足够简单,但又不......
  • 什么是构造函数?Java 中构造函数的重载如何实现?
    构造函数,就像是建筑房屋时的奠基仪式,是Java类中一个特殊的方法,主要用于初始化新创建的对象。每当创建一个类的新实例时,构造函数就会自动调用,负责为这个新对象分配内存,并对其进行必要的设置,确保对象处于可用状态。它有着与类同名的特殊身份,没有返回类型,甚至连void也不需要声明......
  • 在构造方法里获取当前类的泛型
    定义publicclassMyClass<T>{privateClass<T>clazz;publicMyClass(){Typetype=this.getClass().getGenericSuperclass();if(typeinstanceofParameterizedTypeparameterizedType){if(parameterizedType.......
  • 【mybatis】mybatis-plus中Wrapper(条件构造器)简介_常用方法及说明
    1、简介MyBatis-Plus是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。MyBatis-Plus提供了强大的条件构造器(Wrapper),用于构建复杂的SQL查询条件,使得我们不必手写繁琐的SQL语句。这些方法主要定义在com.baomidou.mybatisplus.cor......
  • 代码3:构造最小的HelloWorld程序
    Intro:绪论2:应用视角的操作系统。目的:通过精简程序,了解整个编译过程。一、GCC编译hello.c的全过程.c(源代码)->.i(预编译源代码)-gcc->.S(汇编代码)-as->.o-ld->a.out(一)GCC编译hello.c中只有一行printf("hello,world\n");指令(return由编译器处理,代码......
  • C4D崩溃,出现错误的文件构造如何恢复?
    C4D这款业界领先的3D建模、动画、模拟和渲染软件时,用户可能会遇到各种挑战,其中软件崩溃和错误提示往往是最令人头疼的问题之一。特别是当C4D崩溃后出现“错误的文件构造”这样的提示,不仅会中断创作流程,还可能意味着辛苦工作的成果面临丢失的风险。C4D错误的文件构造怎么办1、文......
  • CF819E Mister B and Flight to the Moon(构造题)
    CF819EMisterBandFlighttotheMoon构造题考虑从小推到大。容易得出\(n=3\)和\(n=4\)的构造方案,如果每次只增加一个点,那么必然会再次覆盖已经完成的边。所以考虑每次增加两个点\(a\)、\(b\),那么增加的边有:它们会向之前所有的点连边。增加边\((a,b)\)。对于点对......
  • NzN的C++之路--拷贝构造函数&&赋值运算符重载
    目录Part1拷贝构造函数一、概念二、特征Part2赋值运算符重载一、运算符重载二、赋值运算符重载三、前置++和后置++重载Part3const成员Part4 取地址及const取地址操作符重载 Part1拷贝构造函数一、概念        拷贝构造函数:只有单个形参,该形参......