【codeforces】【比赛题解】#849 CF Round #431 (Div.2)

cf的比赛越来越有难度了……至少我做起来是这样。

先看看题目吧:点我。

这次比赛是北京时间21:35开始的,算是比较良心。

【A】奇数与结束

"奇数从哪里开始,又在哪里结束?梦想从何处起航,它们又是否会破灭呢?"

给定一个长度为n的序列。确定能不能将序列分成奇数个长度为奇数的非空字串,而且这其中每个子串以奇数开头,以奇数结尾。可以只分成一个(1也是奇数)。

输入

第一行一个正整数n,表示序列长度。

第二行n个整数,表示序列中的元素。

输出

输出"Yes"或"No"来表示能否做到把序列按要求分割。

样例输入1

5
1 0 1 5 1

样例输出1

Yes

样例输入2

4
3 9 9 3

样例输出2

No

题解

当时想了一个n²的DP,之后发现实在是太naive。

讲一下DP思路吧,用f1[i]表示能否将a[1...i]分割成奇数个奇数长度的子串,并且每个子串以奇数开头结尾,f2[i]表示能否分割成偶数个子串。

于是f1[i]=OR(f2[j] (a[j+1...i]长度为奇数并且以奇数开头结尾) ),f2[i]=OR(f1[j] (a[j+1...i]长度为奇数并且以奇数开头结尾) ).

特别的,f1[0]=false,f2[0]=true。

这种做法就可以过了,但是有更优秀的做法:

把序列分成奇数个奇数长度的序列,那么这个序列也是奇数长度的。偶数长度的直接No。

再考虑把序列分成两个以上的序列,那么最开始的序列的起始元素必须是奇数,最末尾的序列的结尾元素也必须是奇数。

这就对应了原序列的第一个与最后一个元素必须是奇数,而这时我们只分一段就好了。

就是说我们只需要判断n的奇偶,a[1]的奇偶和a[n]的奇偶就可以了。

程序:

 1 #include <cstdio>
 2 static const int MAXN = 102;
 3 
 4 int n;
 5 int a[MAXN];
 6 
 7 int main()
 8 {
 9     scanf("%d", &n);
10     for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
11 
12     puts((n & 1) && (a[0] & 1) && (a[n - 1] & 1) ? "Yes" : "No");
13     return 0;
14 }

【B】

目前没做出来,调出来了再说自己的做法吧

先贴标程:

 1 #include <bits/stdc++.h>
 2 #define eps 1e-7
 3 using namespace std;
 4 int read()
 5 {
 6     int x=0,f=1;char ch=getchar();
 7     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
 8     while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 9     return x*f;
10 }
11 int n,a[1007];
12 bool vis[1007];
13 bool check(double k,int b)
14 {
15     memset(vis,false,sizeof(vis));
16     int cnt=0;
17     for (int i=1;i<=n;i++)
18     {
19         if (a[i]-b==1LL*k*(i-1)) 
20         {
21             vis[i]=true;
22             ++cnt;
23         }
24     }
25     if (cnt==n) return false;
26     if (cnt==n-1) return true;
27     int pos1=0;
28     for (int i=1;i<=n;i++)
29         if (!vis[i]&&pos1==0) pos1=i;
30     for (int i=pos1+1;i<=n;i++)
31         if (!vis[i])
32         {
33             if (fabs((double)(a[i]-a[pos1])/(i-pos1)-k)>eps) return false;
34         }
35     return true;
36 }
37 int main()
38 {
39     n=read();
40     for (int i=1;i<=n;i++)
41         a[i]=read();
42     bool ans=false;
43     ans|=check(1.0*(a[2]-a[1]),a[1]);
44     ans|=check(0.5*(a[3]-a[1]),a[1]);
45     ans|=check(1.0*(a[3]-a[2]),a[2]*2-a[3]);
46     if (ans) printf("Yes\n"); else printf("No\n");
47     return 0;
48 }

【C】

题目都没看懂,真的很难受,这题挺难的。

标程:

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 using ll = long long;
 6 using ld = long double;
 7 using D = double;
 8 using uint = unsigned int;
 9 template<typename T>
10 using pair2 = pair<T, T>;
11 
12 #ifdef WIN32
13     #define LLD "%I64d"
14 #else
15     #define LLD "%lld"
16 #endif
17 
18 #define pb push_back
19 #define mp make_pair
20 #define all(x) (x).begin(),(x).end()
21 #define fi first
22 #define se second
23 
24 int main()
25 {
26     int k;
27     scanf("%d", &k);
28     for (int i = 0; i < 26; i++)
29     {
30         int cnt = 1;
31         while ((cnt + 1) * cnt / 2 <= k) cnt++;
32         k -= cnt * (cnt - 1) / 2;
33         for (int j = 0; j < cnt; j++) printf("%c", 'a' + i);
34     }
35     return 0;
36 }

【D】Rooter's Song

"无论目标何在,无论遇见何人,让我们一同将这首歌传唱。"

在平面直角坐标系中,有一个长方形舞台,四角分别是(0,0),(0,h),(w,0),(w,h)。

可以看出在有任何人进入舞台之前,不会有任何碰撞发生。

在舞台的左边界和下边界站着一些舞者。分成两组:

①竖直:站在(xi,0)上,沿着y正方向前进(向上)。

②水平:站在(0,yi)上,沿着x正方向前进(向右)。

按照编舞指导,第i个舞者需要在前ti毫秒内站着不动,然后沿着指定方向以1单位/毫秒的速度前进,直到碰到舞台的边界为止。

当两个舞者碰撞时,她们会立刻改变各自的前进方向,然后继续沿着新的方向前进。

舞者们只要碰到了舞台的边界就会停止,请求出每个舞者最终停下的位置。

输入

第一行有三个数n,w,h。表示舞者数量,舞台的长宽。

接下来n行,每行三个数,gi,pi,ti,表示第i个舞者所在的组(gi=1:竖直组;gi=2:水平组),坐标位置(gi=1则pi=xi;gi=2则pi=yi)以及等待时间。

保证0<xi<w,0<yi<h。并保证没有两个舞者既在相同的组,还有相同的位置和等待时间。

输出

n行,每行两个数xi,yi。表示第i个舞者最终停在哪里。

样例输入1

8 10 8
1 1 10
1 4 13
1 7 1
1 8 2
2 2 0
2 5 14
2 6 0
2 6 1

样例输出1

4 8
10 5
8 8
10 6
10 2
1 8
7 8
10 6

样例输入2

3 2 3
1 1 2
2 1 1
1 1 5

样例输出2

1 3
2 1
1 3

数据范围及提示

1<=n<=100000,2<=w,h<=100000,1<=gi<=2,1<=pi<=99999,0<=ti<=100000。

对于样例数据1,这是对应的图:

对于样例数据2,没有舞者碰撞。

题解

很难的一题,不过我看来比C题简单……

注意到每个舞者出发后,每毫秒其坐标总是有一个加一,故(xi+yi)总是在增加。

而且我们发现,只有(xi+yi)相同的舞者才会碰撞。我们把(xi+yi)的值相同的舞者分在一起处理。

如何确定(xi+yi)的值呢??可以发现对于每个舞者,可以把(pi-ti)近似看做(xi+yi),(pi-ti)相同的舞者可能碰撞,而(pi-ti)不同的不可能碰撞。

我们对舞者按照(pi-ti)排序,处理出(pi-ti)相同的舞者。

对于(pi-ti)相同的舞者,我们如何处理呢?

试着把舞台斜过来看吧!让(0,0)在最下方,(w,h)在最顶端,(0,h)在左侧,(w,0)在最右侧。

这样,对于那些(pi-ti)相同的舞者,即出发后(xi+yi)相同的舞者们,她们在同一时间点必然处在同一水平线上。

并且每过一毫秒,她们向上走√2/2单位,向左或向右走√2/2单位。

这时候的碰撞要如何处理呢?

注意到在没有碰撞发生前,舞者从左到右的顺序是先是水平方向的舞者,坐标从大到小下来,然后是竖直方向的舞者,坐标从小到大往右走。

而所有碰撞都发生了之后呢??舞者的相对位置是不会改变的!原本在最左侧的舞者,仍然在左侧。舞者位置不会交换。

或者……这是另一种形式的交换了呢?注意到在水平方向坐标最大的舞者没有去到她本来应该去的位置,而是去了竖直方向第一个舞者应该去的位置。

是的,她们的位置交换了,但是这种交换很有规律,把舞者分成水平方向和竖直方向,那么水平方向的舞者按顺序要去到竖直方向的舞者按顺序应该去到的位置。依次推下来,就可以确定舞者最终的位置。我不太好解释这种方法的具体实现,先贴代码吧。

排序时要注意第一关键字是(pi-ti),第二关键字是先水平,后竖直,第三关键字是初始坐标,水平的从大到小,竖直的从小到大。

复杂度O(nlogn)

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define F(i,a,b) for(int i=a;i<=b;++i)
 5 #define F2(i,a,b) for(int i=a;i<b;++i)
 6 int n,w,h,g[100002],p[100002],t[100002],I[100002],Ans[100002],Ansg[100002];
 7 inline bool cmp(int x,int y){
 8     if(p[x]-t[x]<p[y]-t[y]) return 1;
 9     else if(p[x]-t[x]>p[y]-t[y]) return 0;
10     else{
11         if(g[x]>g[y]) return 1;
12         else if(g[x]<g[y]) return 0;
13         else{
14             if(g[x]==1) return p[x]<p[y];
15             else return p[x]>p[y];
16         }
17     }
18 }
19 int main(){
20     scanf("%d%d%d",&n,&w,&h);
21     F(i,1,n) scanf("%d%d%d",g+i,p+i,t+i),I[i]=i;
22     std::sort(I+1,I+n+1,cmp);
23     I[n+1]=0; p[0]=99999999; t[0]=-99999999;
24     int hor=0,ver=0;
25     F(i,1,n){
26         if(g[I[i]]==1) ++ver; else ++hor;
27         if(p[I[i]]-t[I[i]]!=p[I[i+1]]-t[I[i+1]]){
28             int j=i-hor-ver+1, k=i-ver+1,l,o;
29             for(l=k,o=j;l<=i;++l,++o)
30                 Ans[I[o]]=p[I[l]],Ansg[I[o]]=g[I[l]];
31             for(;o<=i;++o,++j)
32                 Ans[I[o]]=p[I[j]],Ansg[I[o]]=g[I[j]];
33             ver=hor=0;
34         }
35     }
36     F(i,1,n) if(Ansg[i]==1) printf("%d %d\n",Ans[i],h); else printf("%d %d\n",w,Ans[i]);
37     return 0;
38 }

【E】

没看题,以后再补吧。

转载于:https://www.cnblogs.com/PinkRabbit/p/7466204.html

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

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

相关文章

PaddleDetection支持的数据格式

PaddleDetection支持的数据格式 目前#PaddleDetection支持43种数据格式&#xff1a;coco voc widerface。在这里我们主要说明一下如何使用自定义COCO进行目标检测、实例分割&#xff1b;如何使用自定义VOC数据集进行目标检测。在PaddleDetection新的版本中&#xff0c;我们将数…

[dts]Device Tree机制【转】

转自&#xff1a;https://www.cnblogs.com/aaronLinux/p/5496559.html 转自&#xff1a;http://blog.csdn.net/machiner1/article/details/47805069 ------------------Based on linux 3.10.24 source code 参考/documentation/devicetree/Booting-without-of.txt文档 目录 1.…

AntiSamy测试

AntiSamy为owasp针对xss提供的处理库&#xff0c;可以配置xml策略来决定过滤的内容&#xff0c;比如标签、属性、css等&#xff0c;自定义策略给开发人员使用成本比较高&#xff0c;AntiSamy也提供了几个内置的策略&#xff0c;其安全级别也不同&#xff0c;过滤的内容也不一样…

SoJpt Boot 2.2-3.8 发布,Spring Boot 使用 Jfinal 特性极速开发

开发四年只会写业务代码&#xff0c;分布式高并发都不会还做程序员&#xff1f; 在Spring Boot框架下使用Jfinal特性极速开发,可以在Spring Boot中向使用Jfinal一样使用Enjoy、Aop、Controller等一系列方法(如: getFile(), renderFile....),以及ActiveRecord SoJpt Boot&…

3轴机器人各关节运动学建立,python编程,非常容易理解

分类&#xff1a;机器人学 一、问题描述 如右图所示的三自由度机械臂&#xff0c;关节1和关节2相互垂直&#xff0c;关节2和关节3相互平行。如图所示&#xff0c;所有关节均处于初始状态。 要求: (1) 定义并标注出各关节的正方向&#xff1b; (2) 定义机器人基坐标系&#x…

Win 10 源码一览:0.5T 代码、400 万文件、50 万文件夹

Windows 操作系统本身是不开源的&#xff0c;但是近日微软内核工程师 Axel Rietschin 发表了一篇博客&#xff0c;带大家一窥了 Windows 10 内核的魅力。 Axel 介绍&#xff0c;Windows 10 与 Windows 8.x、7、Vista、XP、2000 和 NT 的代码库是相同的&#xff0c;其中每一代都…

JDK+Tomcat搭建JSP运行环境--JSP基础

一、搭建JSP运行环境之前需要了解的基本知识 配置JSP运行环境之前&#xff0c;我们需要了解JSP的运行机制。只有了解JSP运行机制后&#xff0c;我们才能知道为什么要搭建JSP运行环境?如何去搭建JSP运行环境?为什么要配置Tomcat、JDK&#xff1f; JSP(Java Sever Page)即Java服…

Docker容器的自动化监控实现

本文由 网易云 发布。 近年来容器技术不断成熟并得到应用。Docker作为容器技术的一个代表&#xff0c;目前也在快速发展中&#xff0c;基于 Docker的各种应用也正在普及&#xff0c;与此同时 Docker对传统的运维体系也带来了冲击。我们在建设运维平台的过程中&#xff0c;也需…

人工智能实战小程序之语音_前端开发

1. 人工智能实战小程序之准备工作 2. 人工智能实战小程序之语音_前端开发 今天这部分主要讲小程序前端功能的开发由于我偏后端&#xff0c;css是我的弱项&#xff0c;可能很多人和我一样开发小程序不知道如何下手&#xff0c;希望本篇文章对你有帮助我的学习路线是&#xff1a;…

当TFS/VSTS遇上Power BI

引言众所周知&#xff0c;要对TFS进行深入的图表分析&#xff0c;往往需要依赖于SQL Server Analysis Service和SQL Server Reporting Service。虽然随着TFS对敏捷项目的支持&#xff0c;内置了诸如累积流图、燃尽图等快捷图表&#xff1b;并且在最新的版本中还可以在仪表盘和查…

HashMap深度解析:一文让你彻底了解HashMap

写在前面HashMap是Map族中最为常用的一种&#xff0c;也是 Java Collection Framework 的重要成员。本文首先给出了 HashMap 的实质并概述了其与 Map、HashSet 的关系&#xff0c;紧接着给出了 HashMap 在 JDK 中的定义&#xff0c;并结合源码分析了其四种构造方式。最后&#…

python_线程、进程和协程

线程 Threading用于提供线程相关的操作&#xff0c;线程是应用程序中工作的最小单元。 1 #!/usr/bin/env python2 #codingutf-83 __author__ yinjia4 5 6 import threading,time7 8 def show(arg):9 time.sleep(2) 10 print(线程: str(arg)) 11 12 for i in range(…

第四章:手机平板要兼顾-探究碎片

碎片是什么&#xff1f; 碎片&#xff08;Fragment&#xff09;是一种可以嵌入在活动&#xff08;Activity&#xff09;中的 UI 片段&#xff0c;它能让程序更加合理和充分的利用大屏幕的空间&#xff0c;因而在平板上应用的非常广泛。 碎片的使用方式 静态嵌入动态加载碎片和活…

Android Studio 3.4增可视化资源管理工具 可管理和预览项目资源

经过6个月的开发时间&#xff0c;网络大厂17日发布了最新版的App开发IDE Android Studio 3.4&#xff0c;现在就能够下载使用&#xff0c;除了有超过300个错误修护和稳定度增强之外&#xff0c;在开发、建置和测试App阶段&#xff0c;都推出了一些小的新功能和工具&#xff0c;…

[IoC容器Unity]第三回:依赖注入

上节介绍了&#xff0c;Unity的Lifetime Managers生命周期&#xff0c;Unity具体实现依赖注入包含构造函数注入、属性注入、方法注入&#xff0c;所谓注入相当赋值&#xff0c;下面一个一个来介绍。 2.构造函数注入 Unity利用Resolve方法解析一个对象&#xff0c;都是调用注册类…

Apache CarbonData 1.5.0编译及安装

2019独角兽企业重金招聘Python工程师标准>>> 一、编译环境描述 OpenStack创建五个虚拟机&#xff0c;其中1个主节点&#xff08;hostname为bigdatamaster&#xff09;&#xff0c;4个从节点&#xff08;hostname分别为&#xff0c;bigdataslave1、bigdataslave2、bi…

Filter介绍

Filter 可认为是 Servlet的一种 “ 加强版 ”&#xff0c;它主要用于对用户请求进行预处理&#xff0c; 也可以对HttpServletResponse 进行后处理&#xff0c;是个典型的处理链。Filter 也可对用户请求生成响应&#xff0c;这一 点与Servlet 相同&#xff0c; 但实际上很少会使…

python --- 二分查找算法

二分查找法&#xff1a;在我的理解中这个查找方法为什么会叫二分呢&#xff0c;我认为是将要查询的一个列表分成了两份&#xff0c;然后在利用某个值来进行比较&#xff0c;在一个不断循环的过程中来找出我们要找的某一个值。 废话不多说&#xff0c;先上代码&#xff1a; 1 de…

Java暑假作业

一.《大护法》观影有感 ... 从预告开始就期待着这部影片&#xff0c;在看过一遍后又忍不住二刷&#xff0c;影片观看至第二遍后&#xff0c;对于全片的脉络也更清晰了一点&#xff0c;虽然打着暴力美学的旗子&#xff0c;但《大护法》偏偏更文艺一些。文艺片是没有对错的&a…

使用EasyNetQ组件操作RabbitMQ消息队列服务

RabbitMQ是一个由erlang开发的AMQP(Advanved Message Queue)的开源实现&#xff0c;是实现消息队列应用的一个中间件&#xff0c;消息队列中间件是分布式系统中重要的组件&#xff0c;主要解决应用耦合&#xff0c;异步消息&#xff0c;流量削锋等问题。实现高性能&#xff0c;…