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. 目 ...
随机推荐
- 洛谷P2602 [ZJOI2010]数字计数 题解 数位DP
题目链接:https://www.luogu.com.cn/problem/P2602 题目大意: 计算区间 \([L,R]\) 范围内 \(0 \sim 9\) 各出现了多少次? 解题思路: 使用 ...
- Spring Data JPA使用findAllOrderBy时踩的坑
Spring Data JPA使用findAllOrderBy时踩的坑 按照以往的编程经验,我的写法是这样的: List<ActivityEntity> findAllOrderByWis ...
- 大量SQL的解决方案——sdmap
大量SQL的解决方案--sdmap 最近看到群里面经常讨论大型应用中SQL的管理办法,有人说用EF/EF Core,但很多人不信任它生成SQL的语句:有人说用Dapper,但将SQL写到代码中有些人觉 ...
- react路由的跳转和传参
1.路由的跳转 一.DOM跳转 在需要跳转的页面导入import {Link} from 'react-router-dom',在需要跳转的地方使用link标签的to属性进行跳转,路由配置文件中导出的 ...
- C#多线程与异步
1.什么是异步同步 如果一个方法被调用,调用者需要等待该方法被执行完毕之后才能继续执行,则是同步. 如果方法被调用后立刻返回,即使该方法是一个耗时操作,也能立刻返回到调用者,调用者不需要等待该方法,则 ...
- MongoDB DBA 实践8-----Linux系统Mongodb分片集群部署
在Linux系统中,主要是使用命令行进行mongodb的分片集群部署 一.先决条件 mongodb安装成功,明确路径, MongoDB的几个路径: /var/lib/mongodb /var/log/ ...
- ASP.Net MVC 引用动态 js 脚本
希望可以动态生成 js 发送给客户端使用. layout页引用: <script type="text/javascript" src="@Url.Action( ...
- python中super()
super() : 获取当前类的父类 效果图: 代码: class Animal: def __init__(self,name): self._name = name @property def n ...
- 79.纯 CSS 创作单元素麦当劳金拱门 Logo(原文)
1. 效果图: 效果地址:https://codepen.io/flyingliao/pen/JgavjX 原理:m是伪元素::before弄出来的,::after遮挡中间下方一小块. 感想:学到一个 ...
- P4550 收集邮票
P4550 收集邮票 题目描述 有n种不同的邮票,皮皮想收集所有种类的邮票.唯一的收集方法是到同学凡凡那里购买,每次只能买一张,并且买到的邮票究竟是n种邮票中的哪一种是等概率的,概率均为1/n.但是由 ...