一文带你快速读懂.NET CLI

640?wx_fmt=jpeg

dotnet cli 是 .Net Core 功能中最有用的特性之一。在这篇文章里,我们将介绍几个.Net OSS 工具是如何使用 dotnet cli,并介绍如何在日常开发中使用新的 cli 工具。

正文

关键要点

  • dotnet cli 使得基于. Net 项目的自动化和脚本编写变得非常简单,尤其是与十多年前的. Net 技术相比。

  • dotnet cli 可扩展性模型创造了条件,使得通过 Nuget 将外部.NET 编写的命令行程序集成到你的自动化构建中成为可能。

  • dotnet cli 允许在你的构建脚本中针对解决方案进行测试。

  • dotnet cli 的测试输出有助于更好地使用持续集成 (CI)。

  • 使用 Docker 之类的容器技术比使用 dotnet cli 要容易得多。

随着.NET Core 2.0 的发布,微软拥有了通用、模块化、跨平台和开源平台的下一个主要版本,该版本最初于 2016 年发布。.NET Core 已经创建了许多 API,这些 API 在.NET 框架的当前版本中是可用的。它最初是为了下一代 ASP.NET 解决方案创建的,但现在是许多其他场景的驱动和基础,包括物联网、云和下一代移动解决方案。在关于.NET Core 的第二个系列的文章中,我们将进一步探讨.NET Core 的优点,以及它如何不仅有益于传统的.NET 开发人员,也有益于所有需要为市场提供强健的、高效的和经济的解决方案的技术人员。

InfoQ 的这篇文章是“.NET Core" 系列的一部分。您可以通过 RSS 订阅接收通知。

最近总有人问我,和那些要么迟疑,要么不能退出旧版本、全功能的.NET 的人相比,选择.NET Core 的优势是什么?我在回答中会提到.NET Core 有更好的性能、改进的 csproj 文件格式、改进的 ASP 可测试性,并且它是跨平台的。

作为几个 OSS 工具 (Marten、StructureMap,以及在这个项目中作为例子被引用的Alba) 的作者,对我个人而言最大的优势可能是dotnet cli的出现。我个人认为,结合新的.NET SDK csproj文件格式一起使用时,dotnet cli 工具使我可以更容易创建项目和维护构建脚本。我可以更容易在构建脚本中运行测试,更容易使用和分发 Nuget 包,cli 可扩展性机制非常适合将通过 Nuget 包分发的自定义可执行文件合并到自动构建中。

若要开始使用 dotnet cli,首先要在开发机器上安装.NET SDK。安装完成后,给你一些有用的提示:

  • 将“dotnet”工具全局安装到你的 PATH 中,这样在任何地方都可以通过命令行提示符使用它。

  • dotnet cli 采用 Linux 风格的命令语法,用“–word [value]”这种普通写法表示选择的参数,或者直接用缩写形式“-w [value]”。如果您习惯 Git 或 Node.js 命令行工具,就不会对 dotnet cli 感到陌生。

  • “dotnet --help”将列出已安装的命令和一些基本语法用法。

  • “dotnet --info”将告诉你使用的是哪个版本的 dotnet cli。在持续集成构建中调用此命令可能是一个好主意,以便在本地工作并在构建服务器失败时排除故障,反之亦然。

  • 尽管我在本文中讨论的是.NET Core,但是请注意,你可以在完整.NET 框架的以前版本中使用新的 SDK 项目格式和 dotnet cli。

命令行中的 Hello World

为了简单了解一下 dotnet cli 的一些亮点,让我们假设想构建一个简单的“Hello World”ASP.NET Core 应用程序。不过,为了好玩,我们来添加一些新花样:

1. 我们的 web 服务将在一个单独的项目中进行自动化测试。
2. 我们将通过 Docker 容器部署我们的服务,因为这是很酷的做法 (它展示了更多的 dotnet cli)。
3. 当然,我们将尽可能多地使用 dotnet cli。
如果您想看到这段代码的最终结果,请查看this GitHub repository。

首先,让我们从一个名为“DotNetCliArticle”的空目录开始,并打开您最喜欢的命令行工具到该目录。我们将从使用“dotnet new”命令来生成解决方案文件和新项目开始。.NET SDK 附带了几个用于创建常见项目类型或文件的通用模板,以及其他可作为外接程序使用的模板 (稍后部分将对此进行详细介绍)。要查看在你的机器上可用的模板,可以使用以下命令 dotnet new -help,它应该会给出如下输出:

640?wx_fmt=png

你可能会留意到有一个 sln 模板,它针对的是空解决方案文件。我们将使用该模板,键入 dotnet new sln 命令,该命令将生成以下输出:

The template "Solution File" was created successfully.

默认情况下,此命令将以包含的目录命名解决方案文件。因为我将根目录命名为为“DotNetCliArticle”,所以生成的解决方案文件是“DotNetCliArticle.sln”。

接下来,让我们用以下命令添加“Hello,World”的实际项目:

dotnet new webapi --output HeyWorld

上面的命令意思是将“webapi”模板用到通过“output”参数选择的“HeyWorld”中。这个模板将生成一个精简的 MVC Core 项目结构,适合于无头 API。同样,默认的做法是根据所在的目录命名项目文件,因此我们在目录下得到一个名为“HeyWorld.csproj”的文件,以及所有基本文件,组成一个最小的 ASP.NET MVC Core API 项目。该模板还设置了所有必要的 Nuget 对 ASP.NET Core 的引用,我们在新项目启动时会用到它们。

由于我刚好在一个小型 Git 存储库中构建了它,在使用 Git add 添加了任何新文件之后,我使用 Git status 查看新创建的文件:

new file: HeyWorld/Controllers/ValuesController.cs

new file: HeyWorld/HeyWorld.csproj

new file: HeyWorld/Program.cs

new file: HeyWorld/Startup.cs

new file: HeyWorld/appsettings.Development.json

new file: HeyWorld/appsettings.json

现在,要将新项目添加到我们的空解决方案文件中,您可以像这样使用“dotnet sln”命令:

dotnet sln DotNetCliArticle.sln add HeyWorld/HeyWorld.csproj

现在我们有了一个新的 ASP.NET Core API 服务作为外壳,无需打开 Visual Studio.NET(或者是 JetBrains Rider)。为了更进一步,在编写任何实际代码之前启动我们的测试项目,我发出以下命令:

dotnet new xunit --output HeyWorld.Tests

dotnet sln DotNetCliArticle.sln add HeyWorld.Tests/HeyWorld.Tests.csproj

上面的命令使用 xUnit.NET 创建一个新项目,并将该新项目添加到我们的解决方案文件中。测试工程需要对“HeyWorld”的工程引用,幸运的是,我们可以使用很棒的“dotnet add”工具添加工程引用,如下所示:

dotnet add HeyWorld.Tests/HeyWorld.Tests.csproj reference HeyWorld/HeyWorld.csproj

在打开解决方案之前,我知道还有一些 Nuget 参考资料,我想在测试项目中使用它们。我选择的断言工具是Shoully,因此我将通过对命令行发出另一个调用来添加对最新版本的 shoully 的引用:

dotnet add HeyWorld.Tests/HeyWorld.Tests.csproj package Shouldly

命令行的输出如下:

info : Adding PackageReference for package 'Shouldly' into project 'HeyWorld.Tests/HeyWorld.Tests.csproj'.

log : Restoring packages for /Users/jeremydmiller/code/DotNetCliArticle/HeyWorld.Tests/HeyWorld.Tests.csproj...

info : GET https://api.nuget.org/v3-flatcontainer/shouldly/index.json

info : OK https://api.nuget.org/v3-flatcontainer/shouldly/index.json 109ms

info : Package 'Shouldly' is compatible with all the specified frameworks in project 'HeyWorld.Tests/HeyWorld.Tests.csproj'.

info : PackageReference for package 'Shouldly' version '3.0.0' added to file '/Users/jeremydmiller/code/DotNetCliArticle/HeyWorld.Tests/HeyWorld.Tests.csproj'.

接下来,我想向名为 Alba 的测试项目添加至少一个 Nuget 引用。我将使用AspNetCore2来编写针对新的 web 应用程序的 HTTP 契约测试:

dotnet add HeyWorld.Tests/HeyWorld.Tests.csproj package Alba.AspNetCore2

现在,在使用代码之前先检查一下,我将在命令行发出以下命令构建解决方案中的所有项目,确保它们都可以正常编译:

dotnet build DotNetCliArticle.sln

由于 Alba.AspNetCore2 和 ASP.NET Core Nuget 在 HeyWorld 项目中的引用之间的菱形依赖版本的冲突,所以没有编译。不过不用担心,因为这个问题很容易解决,只需修复 Microsoft.AspNetCore 的版本依赖关系即可。测试项目中的所有 Nuget 都是这样的:

dotnet add HeyWorld.Tests/HeyWorld.Tests.csproj package Microsoft.AspNetCore.All --version 2.1.2

在上面的示例中,使用值为“2.1.2”的“–version”标志将修复对该版本的引用,而不仅仅是使用从 Nuget 提要中找到的最新版本。
为了再次检查我们的 Nuget 依赖问题是否已经解决,我们可以使用下面的命令进行检查,它比重新编译所有东西要更快:

dotnet clean && dotnet restore DotNetCliArticle.sln

作为一个有经验的.NET 开发人员,我非常担心临时 /obj 和 /bin 文件夹中残留的文件。因此,我在 Visual Studio 中使用“Clean Solution”命令,以防我试图改变引用的时候落下些什么。从命令行执行“dotnet clean”命令是完全相同的操作。

同样,针对众所周知的 Nuget 依赖问题,“dotnet restore”命令在解决方案中都试着去解决了。在这种情况下,使用“dotnet restore”可以让我们快速发现任何潜在的冲突或丢失的 Nuget 引用,而无需进行完整的编译,我在自己的工作中主要就采用该命令。在最新版本的 dotnet cli 中,在调用“dotnet build/test/pack/etc”时,会自动为您完成 Nuget 解析 (该行为可以用标记覆盖),这将首先需要 Nuget。

我们调用的“dotnet restore DotNetCliArticle.sln”干净利落地运行完毕,没有错误,所以我们终于可以准备编写一些代码了。让我们打开您选择的 C# 编辑器,向 HeyWorld 添加一个代码文件。测试项目包含一个非常简单的 HTTP 协议测试,它将指定我们希望从新的 HeyWorld 应用程序中的“GET: /”路由获得的行为:

using System.Threading.Tasks;

using Alba;

using Xunit;

namespace HeyWorld.Tests

{

public class verify_the_endpoint

{

[Fact]

public async Task check_it_out()

{

using (var system = SystemUnderTest.ForStartup<Startup>())

{

await system.Scenario(s =>

{

s.Get.Url("/");

s.ContentShouldBe("Hey, world.");

s.ContentTypeShouldBe("text/plain; charset=utf-8");

});

}

}

}

}

结果文件应该保存在具有适当名称 (如 verify_the_endpoints.cs) 的 HeyWorld.Tests 目录。

在没有深入了解 Alba 机制前,我们的新 HeyWorld 应用的首页路由应该写出“Hey, world”。虽然我们还没有在 HeyWorld 应用中编写任何实际的代码,但是我们仍然可以运行这个测试,看看它能够连接正确,还是因为某些“理所当然的理由”而失败。

回到命令行,我可以使用以下命令运行测试项目中的所有测试:

dotnet test HeyWorld.Tests/HeyWorld.Tests.csproj

我们的一个测试会失败,因为还没有实现任何东西,它给了我们这样的输出:

Build started, please wait...

Build completed.

Test run for /Users/jeremydmiller/code/DotNetCliArticle/HeyWorld.Tests/bin/Debug/netcoreapp2.1/HeyWorld.Tests.dll(.NETCoreApp,Version=v2.1)

Microsoft (R) Test Execution Command Line Tool Version 15.7.0

Copyright (c) Microsoft Corporation. All rights reserved.

Starting test execution, please wait...

Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.

Test Run Successful.

Test execution time: 2.4565 Seconds

为了把输出求和,执行了一个测试,但是失败了。我们还可以看到标准的 xUnit 输出,它提供了一些关于测试失败原因的信息。这里需要注意的是,“dotnet test”命令将返回一个退出代码,如果所有测试都通过,则返回 0,表示成功;如果任何测试失败,则返回一个非零退出代码,表示失败。这对于持续集成 (CI) 脚本非常重要,大多数 CI 工具使用任何命令的退出代码来确定构建何时失败。

我认为上面的测试之所以失败是因为“理所当然的原因”,这意味着测试工具似乎能够引导真正的应用程序,我希望得到 404 响应,因为还没有编写任何代码。接下来,让我们为预期的行为实现一个 MVC Core 端点:

public class HomeController : Controller

{

[HttpGet("/")]

public string SayHey()

{

return "Hey, world!";

}

}

(注意,前面的代码应该作为 HeyWorld\startup.cs 文件中的附加类添加)

再次回到命令行,让我们运行前面的“dotnet test HeyWorld.Tests/HeyWorld.Tests.csproj”命令,希望看到这样的结果:

Build started, please wait...

Build completed.

Test run for /Users/jeremydmiller/code/DotNetCliArticle/HeyWorld.Tests/bin/Debug/netcoreapp2.1/HeyWorld.Tests.dll(.NETCoreApp,Version=v2.1)

Microsoft (R) Test Execution Command Line Tool Version 15.7.0

Copyright (c) Microsoft Corporation. All rights reserved.

Starting test execution, please wait...

Total tests: 1. Passed: 1. Failed: 0. Skipped: 0.

Test Run Successful.

Test execution time: 2.4565 Seconds

好了,现在测试通过了,让我们运行实际的应用程序。由于“dotnet new webapi”模板使用进程内的 in-process Kestrel web server 来处理 HTTP 请求,所以要运行新的 HeyWorld 应用程序,我们唯一需要做的一件事就是从命令行使用以下命令启动它:

 dotnet run --project HeyWorld/HeyWorld.csproj

运行上面的命令应该会得到如下输出:

Using launch settings from HeyWorld/Properties/launchSettings.json...

: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]

User profile is available. Using '/Users/jeremydmiller/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.

Hosting environment: Development

Content root path: /Users/jeremydmiller/code/DotNetCliArticle/HeyWorld

Now listening on: https://localhost:5001

Now listening on: http://localhost:5000

Application started. Press Ctrl+C to shut down.

要测试我们现在正在运行的新应用程序,只需在浏览器中导航如下:

640?wx_fmt=jpeg

处理 HTTPS 设置超出了本文的范围。

请再次注意,我假设所有命令都是在将当前目录设置为解决方案根文件夹的情况下执行的。如果当前目录是一个项目目录,并且只有一个 *.csproj。那么,您只需在该目录下键入“dotnet run”即可。现在我们已经有了一个经过测试的 web api 应用程序,接下来让我们将 HeyWorld 放到 Docker 镜像中。使用 the standard template for dockerizing a .NET Core application,我们将向 HeyWorld 项目添加一个 Dockerfile,内容如下:

FROM microsoft/dotnet:sdk AS build-env

WORKDIR /app

Copy csproj and restore as distinct layers

COPY *.csproj ./

RUN dotnet restore

Copy everything else and build

COPY . ./

RUN dotnet publish -c Release -o out

Build runtime image

FROM microsoft/dotnet:aspnetcore-runtime

WORKDIR /app

COPY --from=build-env /app/out .

ENTRYPOINT ["dotnet", "HeyWorld.dll"]


(注意,前面的文本应该保存到项目目录中名为 Dockerfile 的文本文件中——在本例中是 HeyWorld\Dockerfile)。

因为这篇文章仅仅是关于 dotnet cli 的,我只想关注 Dockerfile 中它的两种用法:

1.“dotnet restore”–正如我们在上面学到的,这个命令将解决应用程序的任何 Nuget 依赖关系。

2.“dotnet publish -c Release -o out”–“dotnet publish”命令将构建指定的项目,并将组成应用程序的所有文件复制到给定位置。在我们的例子中,“dotnet publish”将为 HeyWorld 本身复制已编译的程序集、从 Nuget 依赖项引用的所有程序集、配置文件以及 csproj 文件中引用的任何文件。

请注意,在上面的用法中,我们必须通过使用“-c Release”标志明确地告知“dotnet publish”用“Release”配置编译。那些用于编码的 dotnet cli 命令 (例如“build”、“publish”、“pack”)如果没有指定,将以 “Debug”为默认值。注意这种行为,如果要发布用于生产的 Nuget 或应用程序,请记住指定“-c Release”或“-configuration Release”。别怪我没提醒你。

为了完成整个周期,我们现在可以使用以下命令通过 Docker 构建和部署我们的小 HeyWorld 应用程序:

docker build -t heyworld .

docker run -d -p 8080:80 --name myapp heyworld

第一个命令为我们的应用程序“heyworld”构建并本地发布 Docker 镜像。第二个命令实际上作为一个名为“myapp”的 Docker 容器运行我们的应用程序。您可以打开浏览器访问“http://localhost:8080”予以验证。

总结

dotnet cli 使得基于. NET 项目的自动化和脚本编写变得非常简单,尤其是与十多年前的.NET 技术相比。在许多情况下,您甚至可能会避开任何基于任务的构建脚本工具 (Cake、Fake、Rake、Psake 等),而选择只委托给 dotnet cli 的简单 shell 脚本。此外,dotnet cli 可扩展性模型可以很容易地将外部.NET 授权的命令行应用程序通过 Nuget 分布到自动构建程序中。

关于作者

杰里米·米勒 (Jeremy Miller)在密苏里州一个农场社区长大,那里有一群“特别”的人,名叫“树荫技工”。通常,他们不是世界上最有名望的人,但他们有解决机械问题的诀窍,而且做事鲁莽无畏。如果你发现从一辆停在街区的通勤车下伸出来两条腿,那他想必就是名修理工了,他的周围是一些骨架车,堆挤在他那长满灌木、堆满垃圾的院子里。你看到的被遗弃在他周围的打浆机并不是没用的,他们是素材。他会零零碎碎地进行些小调整,然后根据你的需要想出一个创造性的解决方案。尽管名声一般,但一个树荫技工知道如何让东西运行。虽然米勒没有任何特殊的机械能力 (尽管他拥有机械工程学位),但他喜欢把自己当成一个像树荫技工似的开发人员。他的硬盘上肯定到处都是废弃的开源项目碎片。

随着.NET Core 2.0 的发布,微软拥有了通用、模块化、跨平台和开源平台的下一个主要版本,该版本最初于 2016 年发布。.NET Core 已经创建了许多 API,这些 API 在.NET 框架的当前版本中是可用的。它最初是为了下一代 ASP.NET 解决方案创建的,但现在是许多其他场景的驱动和基础,包括物联网、云和下一代移动解决方案。在关于.NET Core 的第二个系列的文章中,我们将进一步探讨.NET Core 的优点,以及它如何不仅有益于传统的.NET 开发人员,也有益于所有需要为市场提供强健的、高效的和经济的解决方案的技术人员。

原文地址:https://www.infoq.cn/article/6EcRA11e1mbzSbo_Xr7h

.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317836.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[POJ 3164]Command Network(最小树形图,朱刘算法)

文章目录titlesolutioncodetitle solution 读完翻译后&#xff0c;很明显就是个朱刘算法的板子题 最小树形图&#xff0c;就是给出一个带权有向图 从中指定一个特殊的结点 root 求一棵以 root 为根的有向生成树 T&#xff0c;且使得 T 中所有边权值最小 简单来说&#xff0c…

CF1553H-XOR and Distance【dp】

正题 题目链接:https://www.luogu.com.cn/problem/CF1553H 题目大意 给出nnn个在[0,2n)[0,2^n)[0,2n)范围内的数字序列aaa。 对于每个x∈[0,2n)x\in[0,2^n)x∈[0,2n)求 min⁡i≠j∣aixorx−ajxorx∣\min_{i\neq j}\ |a_i\ xor\ x-a_j\ xor\ x|i​jmin​ ∣ai​ xor x−aj​…

同余最短路

主要内容 形如&#xff1a; 设问 \(1\) &#xff1a;给定 \(n\) 个整数&#xff0c;求这 \(n\) 个整数在 \(h(h\le2^{63}-1)\) 范围内 能拼凑出多少的其他整数( 个整数可以重复取) 。 设问 \(2\) &#xff1a;给定 \(n\) 个整数&#xff0c;求这 \(n\) 个整数 不能拼凑出的最小…

SP10707 COT2 - Count on a tree II

SP10707 COT2 - Count on a tree II 题意&#xff1a; 给定 n 个结点的树&#xff0c;每个结点有一种颜色。 m 次询问&#xff0c;每次询问给出 u,v&#xff0c;回答 u,v 之间的路径上的结点的不同颜色数。 1< n < 4*10^4 1< m < 10^5 题解&#xff1a; 树上…

[CQOI2018]异或序列

[CQOI2018]异或序列 题意&#xff1a; 给定1个整数K&#xff0c;离线询问[l,r]中有多少子区间xor和K。 题解&#xff1a; 异或有个重要的性质&#xff1a;它的逆运算就是自身 我们维护该数列的前缀异或和a[x],表示1到x的区间异或和&#xff0c;这样问题就变成了在区间[l-1,…

ASP.NET Core 3.0:将会拥有更少的依赖

在ASP.NET Core项目中&#xff0c;我们使用一个叫做Microsoft.AspNetCore.App的综合包。它也被称为ASP.NET Core Shared Framework&#xff0c;在ASP.NET Core Shared Framework之中包含了很多依赖项&#xff0c;它能满足一般应用的需求。但是如果你查看它的依赖项&#xff0c;…

CSP2020洛谷P7077:函数调用

解析 没做出来… qwq 自己只能想到拓扑开vector把每个函数搞成一个奇怪的加法标记和乘法标记的结合 极限数据卡一卡还是nm的 得分纯玄学qwq 本题的关键是乘法相当于把函数调用多次 这样就可以利用和全是加法类似的策略拓扑统计每个函数的调用次数 使问题得以解决 要注意部分…

CF1616H Keep XOR Low(Trie 树上 DP)

CF1616H Keep XOR Low 给你 \(n\) 个整数 \(a_1,a_2,\cdots,a_n\) 和一个整数 \(x\)。 你需要求出 \(\{1,2,\cdots,n\}\) 的一个子集 \(S\)&#xff0c;满足 \(S\) 中任意两个不同的元素 \(i,j\)&#xff0c;满足 \(a_i~{\rm xor}~a_j\le x\)。 求选取 \(S\) 的方案数&#xff…

[UVA - 11865]Stream My Contest(最小树形图+朱刘算法)

本题过于简单&#xff0c;朱刘算法模板题&#xff0c;考虑二分一下带宽即可titlecodetitle code #include <cstdio> #include <cstring> #include <iostream> using namespace std; #define MAXN 65 #define MAXM 100005 #define int long long #define in…

CSP2021NOIP2021游记

CSP Day -? 初赛 初赛考前没怎么复习&#xff0c;反倒是理直气壮的翘了一周晚修&#xff08;虽然后面就一直翘了&#xff09;。 开考之后才发现要拿那几张纸&#xff0c;监考让我考完再出去拿。 选择题很简单&#xff0c;没有啥犹豫的写完了&#xff0c;第一道读程序写结果好…

P3226 [HNOI2012]集合选数(状压 DP)

P3226 [HNOI2012]集合选数 要求选出集合 \(S\) 满足如果 \(x\) 选择了&#xff0c;\(2x\) 和 \(3x\) 都不能选择。 求 \(\{1,2,\dots,n\}\) 的符合要求的子集数量。 \(n\le 10^5\)。 发现对所有除去 \(2,3\) 因子后不同的数&#xff0c;他们之间没有关联&#xff0c;完全可以分…

微软上线Try .NET,支持在浏览器运行C#代码

微软Try .NET项目近期上线&#xff0c;这一项目允许用户通过浏览器运行和编写C#代码&#xff0c;同时还支持完整的代码提示。用户可以通过访问这一项目官网&#xff08;点此进入&#xff09;对Try .NET这一项目进行简单了解。该项目允许开发人员在浏览器中运行和编辑C#代码片段…

第46届ICPC亚洲区域赛(沈阳)L-Perfect Matchings【dp,组合数学】

正题 题目链接:https://ac.nowcoder.com/acm/contest/24346/L 题目大意 有一张2n2n2n个点的完全图&#xff0c;在上面删除一棵生成树&#xff0c;然后求这张图的完全匹配方案数。 1≤n≤20001\leq n\leq 20001≤n≤2000 解题思路 考虑容斥&#xff0c;可以dpdpdp出fi,j,0/1f…

CSP2019洛谷P5666:树的重心

解析 毒题 细节有亿点点多 我一开始的思路是没有问题的 尝试统计有多少种方案能砍出大小在一个区间的子树、 当时的想法是线段树合并 但是这个玩意在需要保留原树的情况下空间复杂度炸没了… 因为我垃圾的实现一个dfs里面就玩了七遍merge函数… 空间常数飞起 然后分数就和暴力…

[LOJ]体育成绩统计 / Score (无脑模拟,没有脑子,就是上!)

题目 好久没敲过恶心的模拟题了&#xff0c;莫名有点怀念是什么鬼&#xff0c;我还记得我的zamjena 没啥想说的&#xff0c;这道题就是没智商有码力的 纯粹是纪念一下今天上午直接肝了的两个半小时&#xff0c;真的一点思维都不需要有&#xff0c;直接上&#xff01;&#xff0…

P7137 [THUPC2021 初赛] 切切糕(博弈 概率)

P7137 [THUPC2021 初赛] 切切糕 -> 双倍经验&#xff1a;Game on Sum (Hard Version) 有 \(n\) 块方蛋糕&#xff0c;绝顶聪明的 Sight 和 Sirrel 决定将每块蛋糕都分成两块各自品尝。Sight 会依次将每块蛋糕分成两块&#xff0c;而 Sirrel 有 \(m\) 次优先选择权。 对于 \(…

程序员修仙之路--设计一个实用的线程池

菜菜呀&#xff0c;我最近研究技术呢&#xff0c;发现线上一个任务程序线程数有点多呀CEO,CTO,CFO于一身的CXOx总&#xff0c;你学编程呢&#xff1f;菜菜作为公司总负责人&#xff0c;我以后还要管理技术部门呢&#xff0c;怎么能不会技术呢CEO,CTO,CFO于一身的CXO&#xff08…

Code Names

Code Names 题意&#xff1a; 如果一个字符串通过交换两个位置可以得到另一个字符串&#xff08;也就是两个字符串只有两个位置不一样且为交换关系&#xff09;&#xff0c;我们称这两个字符串为替代关系。 现在给出n个字符串&#xff0c;求一个集合&#xff0c;使得集合内的…

CSP2019洛谷P5665:划分(单调队列,高精度)

解析 自己写的时候写了二维单调队列优化的64分 一次过还是可以满意了啦 正解的关键结论是最优的方案的最后一段一定尽可能的短 原因嘛…显然 贪心的想&#xff0c;再最后一段的段首可以往前放的情况下肯定是要往前放的&#xff0c;这样代价更小&#xff0c;同时对后面的选取也…

P7962-[NOIP2021]方差【dp,差分】

正题 题目链接:https://www.luogu.com.cn/problem/P7962 题目大意 给出一个长度为nnn的序列aaa&#xff0c;你每次可以让一个ai(1<i<n)ai−1ai1−aia_i(1<i<n)a_{i-1}a_{i1}-a_iai​(1<i<n)ai−1​ai1​−ai​&#xff0c;求能变出的最小方差。 1≤n≤400,…