20190708三人开黑CF模拟赛
7月8号晚上8点和两位巨佬开了一场虚拟cf: [Helvetic Coding Contest 2018 online mirror (teams allowed, unrated)]
我这么蔡,只AC了A2、C1、C2、E1(被巨佬吊打)

我就说一下我写的几道题吧:
The stardate is 1983, and Princess Heidi is getting better at detecting the Death Stars. This time, two Rebel spies have yet again given Heidi two maps with the possible locations of the Death Star. Since she got rid of all double agents last time, she knows that both maps are correct, and indeed show the map of the solar system that contains the Death Star. However, this time the Empire has hidden the Death Star very well, and Heidi needs to find a place that appears on both maps in order to detect the Death Star.
The first map is an N × M grid, each cell of which shows some type of cosmic object that is present in the corresponding quadrant of space. The second map is an M × N grid. Heidi needs to align those two maps in such a way that they overlap over some M × M section in which all cosmic objects are identical. Help Heidi by identifying where such an M × M section lies within both maps.
Input
The first line of the input contains two space-separated integers N and M (1 ≤ N ≤ 2000, 1 ≤ M ≤ 200, M ≤ N). The next N lines each contain M lower-case Latin characters (a-z), denoting the first map. Different characters correspond to different cosmic object types. The next M lines each contain N characters, describing the second map in the same format.
Output
The only line of the output should contain two space-separated integers i and j, denoting that the section of size M × M in the first map that starts at the i-th row is equal to the section of the second map that starts at the j-th column. Rows and columns are numbered starting from 1.
If there are several possible ways to align the maps, Heidi will be satisfied with any of those. It is guaranteed that a solution exists.
翻译后的人话:
给你两个矩阵,前一个\(N×M\),后一个\(M×N\),然后再两个矩阵中识别一个\(M×M\)的矩阵,这个矩阵都存在于两个矩阵中
好水啊,可以用kmp,不过我太蔡不会于是直接hash暴力匹配
这里用了单哈希,参考了巨佬队友tanao_的代码,我双哈希不知道为什么T飞(可能是我太蔡了)
直接上代码(把注释去掉就变成双hash了):
#include <cstdio>
#include <cctype>
#include <iostream>
#define reg register
#define int long long
using namespace std;
const int MaxN=2001;
const int MaxM=201;
const int inf=0x7ffffffffffffff; // 14 f
const int base1=131;
const int base2=13131;
const int p1=4503599627370001ll;
const int p2=4503599627391001ll;
int n,m;
string s1[MaxN],s2[MaxN];
int s1hash1[MaxN],s2hash1[MaxM][MaxN];
int s1hash2[MaxN],s2hash2[MaxM][MaxN];
template <class t> inline void rd(t &s)
{
s=0;
reg char c=getchar();
while(!isdigit(c))
c=getchar();
while(isdigit(c))
s=(s<<3)+(s<<1)+(c^48),c=getchar();
return;
}
inline int gethash1(string s)
{
reg int res=0;
for(int i=0;i<s.length();++i)
res=(res*base1+s[i])%p1;
return res;
}
inline int gethash2(string s)
{
reg int res=0;
for(int i=0;i<s.length();++i)
res=(res*base2+s[i])%p2;
return res;
}
inline bool ck(int x,int y)
{
for(int i=1;i<=m;++i)
// if(s1hash1[x+i-1]!=s2hash1[i][y]||s1hash2[x+i-1]!=s2hash2[i][y])
if(s1hash1[x+i-1]!=s2hash1[i][y])
return false;
return true;
}
signed main(void)
{
rd(n);rd(m);
for(int i=1;i<=n;++i)
cin>>s1[i];
for(int i=1;i<=m;++i)
cin>>s2[i];
for(int i=1;i<=n;++i)
{
s1hash1[i]=gethash1(s1[i]);
// s1hash2[i]=gethash2(s1[i]);
}
for(int i=1;i<=m;++i)
for(int j=1;j<=n-m+1;++j)
{
s2hash1[i][j]=gethash1(s2[i].substr(j-1,m));
// s2hash2[i][j]=gethash2(s2[i].substr(j-1,m));
}
for(int i=1;i<=n-m+1;++i)
for(int j=1;j<=n-m+1;++j)
if(ck(i,j))
return printf("%lld %lld",i,j),0;
return 0;
}
Rebel spy Heidi has just obtained the plans for the Death Star from the Empire and, now on her way to safety, she is trying to break the encryption of the plans (of course they are encrypted – the Empire may be evil, but it is not stupid!). The encryption has several levels of security, and here is how the first one looks.
Heidi is presented with a screen that shows her a sequence of integers A and a positive integer p. She knows that the encryption code is a single number S, which is defined as follows:
Define the score of X to be the sum of the elements of X modulo p.
Heidi is given a sequence A that consists of N integers, and also given an integer p. She needs to split A into 2 parts such that:
- Each part contains at least 1 element of A, and each part consists of contiguous elements of A.
- The two parts do not overlap.
- The total sum S of the scores of those two parts is maximized. This is the encryption code.
Output the sum S, which is the encryption code.
Input
The first line of the input contains two space-separated integer N and p (2 ≤ N ≤ 100 000, 2 ≤ p ≤ 10 000) – the number of elements in A, and the modulo for computing scores, respectively.
The second line contains N space-separated integers which are the elements of A. Each integer is from the interval [1, 1 000 000].
Output
Output the number S as described in the problem statement.
样例1
输入
4 10
3 4 7 2
输出
16
经过印度女工翻译后的人话:
把长度为n的序列分成两个部分,使每个子序列的和对p取模后的结果的和最大
样例解释1:
\((3+4) mod 10+(7+2) mod 10 = 16\)
\(n<=100000\) 直接前缀和暴力枚举断点水过
Code:
#include <cstdio>
#include <cctype>
#include <algorithm>
#define int long long
#define reg register
using namespace std;
const int MaxN=100001;
template <class t> inline void rd(t &s)
{
s=0;
reg char c=getchar();
while(!isdigit(c))
c=getchar();
while(isdigit(c))
s=(s<<3)+(s<<1)+(c^48),c=getchar();
return;
}
int a[MaxN],f[MaxN];
inline int getsum(int l,int r)
{
return f[r]-f[l-1];
}
signed main(void)
{
int n,p;
reg int ans=0;
rd(n);rd(p);
for(int i=1;i<=n;++i)
rd(a[i]),f[i]=f[i-1]+a[i];
for(int i=1;i<n;++i)
ans=max(ans,(getsum(1,i)%p)+(getsum(i+1,n)%p));
printf("%lld",ans);
return 0;
}
Heidi has now broken the first level of encryption of the Death Star plans, and is staring at the screen presenting her with the description of the next code she has to enter. It looks surprisingly similar to the first one – seems like the Empire engineers were quite lazy...
Heidi is once again given a sequence A, but now she is also given two integers k and p. She needs to find out what the encryption key S is.
Let X be a sequence of integers, and p a positive integer. We define the score of X to be the sum of the elements of X modulo p.
Heidi is given a sequence A that consists of N integers, and also given integers k and p. Her goal is to split A into k part such that:
- Each part contains at least 1 element of A, and each part consists of contiguous elements of A.
- No two parts overlap.
- The total sum S of the scores of those parts is maximized.
Output the sum S – the encryption code.
Input
The first line of the input contains three space-separated integer N, k and p (k ≤ N ≤ 20 000, 2 ≤ k ≤ 50, 2 ≤ p ≤ 100) – the number of elements in A, the number of parts A should be split into, and the modulo for computing scores, respectively.
The second line contains N space-separated integers that are the elements of A. Each integer is from the interval [1, 1 000 000].
Output
Output the number S as described in the problem statement.
上一题的升级版
人话:把长度为n的序列分成k个部分,使每个子序列的和对p取模后的结果的和最大
很明显,考虑dp
\(f[i][j]\) 表示前i个数分成j段时的最大结果
转移方程很简单,
\(f[i][j]=max(f[i][j],f[k][j-1]+(g[i]-g[k])mod p)\) \((0<=k<i)\)
解释一下,g[i]是前缀和,\(f[k][j-1]\)表示在第k个数断j-1个点时的最大结果,\((g[i]-g[k])\)就是k+1~i这段序列和,k是用来枚举用的,看不懂建议先去做一些基础的dp
分析一下复杂度\(O(n^2k)\),最大计算次数为\(2.0×10^{10}\),20亿,好,信心满满地相信CF的机子交上去
考虑优化,我们是不是可以把一个n搞成p来减少时间复杂度呢
\(f[i][j]\)表示前i个数对p取模后为i,分成j段时的最大结果
显而易见,首先,因为dp数组的第一维的范围只有\([0,p-1]\),那么\(f[i][j]\)只有可能从\(f[k][j-1]\)\((0<=k<p)\)转移过来,那么对应断点所得新的子序列的和就是\((g[i]-k)modp\),所以可以得到状态转移方程
\(f[i][j]=max(f[i][j],f[k][j-1]+(g[i]-k)modp)\)\(0<=k<p\)
于是,Code就出来了:
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <cstring>
#define reg register
#define int long long
using namespace std;
const int MaxN=20001;
const int MaxK=51;
template <class t> inline void rd(t &s)
{
s=0;
reg char c=getchar();
while(!isdigit(c))
c=getchar();
while(isdigit(c))
s=(s<<3)+(s<<1)+(c^48),c=getchar();
return;
}
int n,k,p;
int a[MaxN],g[MaxN];
int f[MaxN][MaxK];
signed main(void)
{
memset(f,0x80,sizeof f);f[0][0]=0;
rd(n);rd(k);rd(p);
for(int i=1;i<=n;++i)
rd(a[i]),g[i]=g[i-1]+a[i],g[i]%=p;
for(int i=1;i<=n;++i)
for(int j=k;j;--j)
for(int k=0;k<p;++k)
f[g[i]][j]=max(f[g[i]][j],f[k][j-1]+(g[i]+p-k)%p);
printf("%lld",f[g[n]][k]);
return 0;
}
The Rebel fleet is afraid that the Empire might want to strike back again. Princess Heidi needs to know if it is possible to assign R Rebel spaceships to guard B bases so that every base has exactly one guardian and each spaceship has exactly one assigned base (in other words, the assignment is a perfect matching). Since she knows how reckless her pilots are, she wants to be sure that any two (straight) paths – from a base to its assigned spaceship – do not intersect in the galaxy plane (that is, in 2D), and so there is no risk of collision.
Input
The first line contains two space-separated integers R, B(1 ≤ R, B ≤ 10). For 1 ≤ i ≤ R, the i + 1-th line contains two space-separated integers xi and yi (|xi|, |yi| ≤ 10000) denoting the coordinates of the i-th Rebel spaceship. The following B lines have the same format, denoting the position of bases. It is guaranteed that no two points coincide and that no three points are on the same line.
Output
If it is possible to connect Rebel spaceships and bases so as satisfy the constraint, output Yes, otherwise output No (without quote).
使用谷歌翻译然后看看样例再大胆的猜想一下就看懂题意了,其实我当时也不知道我能一次A
还好我当时猜对了题意
有R个叛军基地和B个守卫基地,要求一种匹配,使每一个叛军基地都和一个守卫基地连线,如果存在一种连线方法能让每一个基地都有匹配并且这些线段两两不相交,那么输出Yes,否则输出No
\(1<=R,B<=10\),直接暴力枚举每一种情况,判断;如果\(R!=B\),直接输出No
暴力好写,但是怎么判断两条线段是否相交呢?
这里使用了快速排斥实验和跨立实验法,参考一位巨佬的博客(好几个月前看过,好不容易翻出来的)
快速排斥实验:判断两条线段在 x 以及 y 坐标的投影是否有重合
人话:若A线段中x较大的端点比B线段中x较小的端点的x要小,
或A线段中y较大的端点比B线段中y较小的端点的y要小,则AB线段不相交

如图,图(1)和图(2)可以自己推出符合快速排斥,可图(3)就不符合快速排斥了
那么就要用到跨立实验法,也就是矢量叉积:
设矢量 \(P = (x1, y1),Q = ( x2, y2 )\),则矢量叉积定义为:\(P×Q = x1×y2 - x2×y1\)
有$P×Q = - ( Q×P ) $和 \(P×( - Q ) = - ( P×Q )\)
若 \(P×Q > 0\) , 则 \(P\) 在 \(Q\) 的顺时针方向。
若 \(P×Q < 0\) , 则 \(P\) 在 \(Q\) 的逆时针方向。
若 \(P×Q = 0\) , 则 \(P\) 与 \(Q\) 共线,但可能同向也可能反向。
(1):
如果两线段相交那么就意味着它们互相跨立,即如上图点 A 和 B 分别在线段 CD 两侧,点 C 和 D 分别在线 AB 两侧。
判断 A 点与 B 点是否在线段 DC 的两侧,即向量 A-D 与向量 B-D 分别在向量 C-D 的两端,也就是其叉积是异号的,即 。
同时也要证明 C 点与 D 点在线段 AB 的两端,两个同时满足,则表示线段相交。
(2):临界情况,也就是上式恰好等于 0 的情况下:

当出现如上图所示的情况的时候,显然,这种情况是相交的。只要将等号直接补上即可。
(3)再看看上面我给的图(3):
当出现如上所示的情况的时候,叉积都为 0, 可以通过跨立实验,但是两个线段并没有交点。不过还好,这种情况在第一步快速排斥已经被排除了。
给出AC代码:
#include <cstdio>
#include <cctype>
#include <iostream>
#include <cstdlib>
#define reg register
using namespace std;
const int MaxN=11;
struct Node
{
int x,y;
}a[MaxN],b[MaxN];
struct Line
{
int xa,xb,ya,yb;
}E[10001];
int en;
template <class t> inline void rd(t &s)
{
s=0;
reg char c=getchar();
while(!isdigit(c))
c=getchar();
while(isdigit(c))
s=(s<<3)+(s<<1)+(c^48),c=getchar();
return;
}
inline bool tix(Line x,Line y)
{
if ((x.xa > x.xb ? x.xa : x.xb) < (y.xa < y.xb ? y.xa : y.xb) ||
(x.ya > x.yb ? x.ya : x.yb) < (y.ya < y.yb ? y.ya : y.yb) ||
(y.xa > y.xb ? y.xa : y.xb) < (x.xa < x.xb ? x.xa : x.xb) ||
(y.ya > y.yb ? y.ya : y.yb) < (x.ya < x.yb ? x.ya : x.yb))
return false;
if ((((x.xa - y.xa)*(y.yb - y.ya) - (x.ya - y.ya)*(y.xb - y.xa))*
((x.xb - y.xa)*(y.yb - y.ya) - (x.yb - y.ya)*(y.xb - y.xa))) > 0 ||
(((y.xa - x.xa)*(x.yb - x.ya) - (y.ya - x.ya)*(x.xb - x.xa))*
((y.xb - x.xa)*(x.yb - x.ya) - (y.yb - x.ya)*(x.xb - x.xa))) > 0)
return false;
return true;
}
int R,B;
bool vis[MaxN];
inline bool ck()
{
for(int i=1;i<=R;++i)
for(int j=i+1;j<=B;++j)
if(tix(E[i],E[j]))
return false;
return true;
}
inline void dfs(int dep)
{
if(dep>R)
{
if(ck())
{
puts("Yes");
exit(0);
}
return;
}
for(int i=1;i<=B;++i)
if(!vis[i])
{
vis[i]=true;
E[dep].xa=a[dep].x;
E[dep].ya=a[dep].y;
E[dep].xb=b[i].x;
E[dep].yb=b[i].y;
dfs(dep+1);
vis[i]=false;
}
return;
}
signed main(void)
{
rd(R);rd(B);
if(R!=B)
return puts("No"),0;
for(int i=1;i<=R;++i)
{
rd(a[i].x);rd(a[i].y);
}
for(int i=1;i<=B;++i)
{
rd(b[i].x);rd(b[i].y);
}
dfs(1);
puts("No");
return 0;
}
第一次写cf的解题报告awa
20190708三人开黑CF模拟赛的更多相关文章
- 20190728三人开黑517codingACM模拟赛
三人组队开黑ACM膜你赛 果然我最蔡 我就写了ACF所以就写这些吧awa Problem A 人话:给你一个w×h的矩形蛋糕,然后告诉你两个蜡烛的坐标,两个蜡烛都在网格点上且不在蛋糕边缘,问如何切一刀 ...
- 20190710双人开黑CF模拟赛
Codeforces Round #571 (Div. 2) 日常被tanao_大佬带飞,我AC了A和C(B题没了...否则tanao_大佬肯定把我吊打) A. Vus the Cossack and ...
- NOI.AC NOIP模拟赛 第三场 补记
NOI.AC NOIP模拟赛 第三场 补记 列队 题目大意: 给定一个\(n\times m(n,m\le1000)\)的矩阵,每个格子上有一个数\(w_{i,j}\).保证\(w_{i,j}\)互不 ...
- 两个乒乓球队进行比赛,各出三人。 甲队为a,b,c三人,乙队为x,y,z三人。 已抽签决定比赛名单。 有人向队员打听比赛的名单。 a说他不和x比,c说他不和x,z比, 请编程序找出三队赛手的名单。
题目:两个乒乓球队进行比赛,各出三人. 甲队为a,b,c三人,乙队为x,y,z三人. 已抽签决定比赛名单. 有人向队员打听比赛的名单. a说他不和x比,c说他不和x,z比, 请编程序找出三队赛手的名单 ...
- 计蒜客T2202 数三角形(提高组2017模拟赛(三)day2T3) LZOJ3878攻略
今天模拟赛考了一道计蒜客NOIP2017模拟赛(三)day2T3的数三角形,原题链接 https://nanti.jisuanke.com/t/T2202 ,LZOJ3878攻略.场上想了很久都没转化 ...
- 代码实现:两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。 已抽签决定比赛名单。有人向队员打听比赛的名单。 a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单
/*两个乒乓球队进行比赛,各出三人.甲队为a,b,c三人,乙队为x,y,z三人. 已抽签决定比赛名单.有人向队员打听比赛的名单. a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单.*/ ...
- python基础练习题(题目 两个乒乓球队进行比赛,各出三人。甲队为a,b,c三人,乙队为x,y,z三人。已抽签决定比赛名单。有人向队员打听比赛的名单。a说他不和x比,c说他不和x,z比,请编程序找出三队赛手的名单)
day14 --------------------------------------------------------------- 实例022:比赛对手 题目 两个乒乓球队进行比赛,各出三人. ...
- NOIp2018模拟赛三十六
好久没打模拟赛了...今天一样是两道国集,一道bzoj题 成绩:13+0+95=108 A题开始看错题了...导致样例都没看懂,结果xfz提醒我后我理解了一个我自认为正确的题意(事实证明我和xfz都错 ...
- 冲刺$\mathfrak{CSP-S}$集训模拟赛总结
开坑.手懒并不想继续一场考试一篇文. 既没必要也没时间侧边栏的最新随笔题解反思相间也丑 而且最近越来越懒了竟然都不写题解了……开坑也是为了督促自己写题解. 并不想长篇大论.简要题解也得写啊QAQ. 目 ...
随机推荐
- MySQL之分库分表(MyCAT实现)
分库分表介绍 随着微服务这种架构的兴起,我们应用从一个完整的大的应用,切分为很多可以独立提供服务的小应用.每个应用都有独立的数据库. 数据的切分分为两种: 垂直切分:按照业务模块进行切分,将不同模块的 ...
- 21.pyinstaller相关参数
pyinstaller相关参数 命令 描述 -F, ...
- K8s 实践 | 如何解决多租户集群的安全隔离问题?
作者 | 匡大虎 阿里巴巴技术专家 导读:如何解决多租户集群的安全隔离问题是企业上云的一个关键问题,本文主要介绍 Kubernetes 多租户集群的基本概念和常见应用形态,以及在企业内部共享集群的业 ...
- 【tf.keras】使用手册
目录 0. 简介 1. 安装 1.1 安装 CUDA 和 cuDNN 2. 数据集 2.1 使用 tensorflow_datasets 导入公共数据集 2.2 数据集过大导致内存溢出 2.3 加载 ...
- 【转】Java集合框架面试问题集锦
Java集合框架(例如基本的数据结构)里包含了最常见的Java常见面试问题.很好地理解集合框架,可以帮助你理解和利用Java的一些高级特性.下面是面试Java核心技术的一些很实用的问题. Q:最常见的 ...
- vue超简单加载字体方法,解决scss难加载字体的问题
vue超简单加载字体方法,解决scss难加载字体的问题 scss在加载字体方面一直不太好用,需要繁杂的配置才能达到想要的效果,这里说一种非常简单的方法 在App.vue的style标签下引入字体文件后 ...
- 2019 牛客国庆集训day1 2019 点分治
题目链接:https://ac.nowcoder.com/acm/contest/1099/I 点分治,计算路径数的时候,先将每个点到根的距离模2019,计算的时候就可以O(n)求出数目,对于模201 ...
- Burpsuite设置拦截response
一.Burpsuite设置拦截HTTP/HTTPS代理 1, .拦截修改request 首先进入Proxy-Options-Intercept Client Requests设置request拦截的规 ...
- select的disabled形式的数据,使用表单序列化方式无法将数据传到后台
之前博客里有讲述到使用表单序列化的方式传递数据到后台,那里是将数据为disabled形式的内容剔除掉了,所以为disabled的select肯定也是传不过去的. 解决方式: 1.在序列化表单方法之前将 ...
- 2019CSP复赛游记
Day 0 作为一个初三的小蒟蒻…… 什么算法都不会打…… 做一道LCA+生成树的图论题调了两个小时…… 明日裸考…… Day 1 Morning 买了两个士力架,带了一盒牛奶,准备在考场上食用(这个 ...