摘要:
题目链接:Link Solution 第一次过计算几何黑题,写篇题解纪念一下。 问题一:详见代码 问题二:详见代码 问题三:很简单的问题,不会去看蓝书 问题四:由于半径为r,圆心到直线的距离一定为r,满足该条件的点的轨迹是两条直线。而想要过定点,圆心到该点的距离也一定为r,满足该条件的点的轨迹是一个 阅读全文
摘要:
题目链接:Link Solution 作为蒟蒻的我在CSDN上找了篇题解借鉴了一下 原文,我这篇题解算是对原题解的补充说明。 #include<cstdio> #include<cmath> const double pi=acos(-1.0); double area(double a,doubl 阅读全文
摘要:
题目链接:Link Solution 记忆化动态规划 什么鬼 这题是一道典型的插头DP(轮廓线动态规划),由于如果不记录轮廓线无法转移且m和n中至少有一个不超过10,所以可以用二进制编码将轮廓线计入状态,详细推导过程见《算法竞赛入门经典训练指南》P384。 这是裸的插头DP: #include<cs 阅读全文
摘要:
题目链接:Link Solution 这题是典型的AC自动机,一个小优化是把所有不存在的边补上,使得所有的转移一视同仁,减少while语句来常数优化。 贴代码: #include<cstdio> #include<cstring> #include<queue> #include<map> usin 阅读全文
摘要:
题目链接:Link Solution 这题的主要思想就是数形结合。设比赛总长度为1,其中游泳长度为x,自行车长度为y,赛跑长度为 1-x-y,则选手i打败选手j(非并列)的条件是 \(\dfrac{x}{v_i}+\dfrac{y}{u_i}+\dfrac{1-x-y}{w_i}<\dfrac{x} 阅读全文
摘要:
题目链接:Link Solution 每次询问都能得到一个半平面,它们的并就是可能的区域(别忘了考虑房间的边界),特判一下“Same”就行了。 贴代码: #include<cstdio> #include<cstring> #include<cmath> #include<vector> #incl 阅读全文
摘要:
题目链接:Link Solution 第一次写Trie,写篇题解纪念一下...... 令d(i)表示从字符i开始的字符串(即后缀 S[i...L-1])的分解方案数,则d(i)=sum{d(i+len(x)) | 单词x是 S[i...L-1]的前缀}。 显然,关键点就在判断前缀上。可以把所有的单词 阅读全文
摘要:
题目链接:Link Solution 由于素数都是正数,因此可以把素数预处理成一个队列,每次都尽量往上加。这样就可以用O(n)的时间算出方案数。 #include<cstdio> inline bool isp(int a) { for(int i=2;i*i<=a;i++) if(a%i==0) 阅读全文
摘要:
题目链接:Link Solution 这题坑了我很长时间。。。血篇题解纪念一下。。。 如果枚举每一条线段并计算它露出的部分会非常麻烦,可以考虑把这个地图分割成一些薯条竖条,使得每个区域内露出的部分无交点,显然按照线段交点的x坐标分割比较好。 于是,我们得出了如下代码: #include<cstdio 阅读全文
摘要:
题目链接:Link Problem Solution 首先,我们可以发现:交换相邻的两头奶牛,对其它奶牛的危险值没有影响。设这两头奶牛分别为\((s_1,w_1),(s_2,w_2)\),之前所有奶牛的体重和为\(sw\),则1放在2前面更优意味着: \[max(sw-s_1,sw+w_1-s_2) 阅读全文
摘要:
题目链接:Link Solution 做这题时一开始我想用IDA*,后来发现需要判断是否有解,便改用状态压缩bfs。事实上,移动时石头和机器人是一样的,所以可以很容易的压缩到一个变量里,判重时可以将树的状态(压缩过)和机器人的位置分两个维度。 代码如下: #include<cstdio> #incl 阅读全文
摘要:
题目链接:Link Solution 小心溢出! 小心溢出! 小心溢出! 这道题是一个很典型的状压DP,唯一要注意的是要小心溢出。 刷表法: #include<cstdio> #include<cstring> using namespace std; const int maxn=16; int 阅读全文
摘要:
题目链接:Link Solution 这题的状态转移方程很容易想出(分同时去掉、去头、去尾三种情况),但字典序最小不好处理。我是在状态转移的同时计算答案,没想到string居然没有炸掉.... 贴代码: #include<cstdio> #include<cstring> #include<stri 阅读全文
摘要:
题目链接:Link Solution 紫书上的思路很容易理解,但时间复杂度太高。在网上搜了半天终于在维基百科上搜到了O(1)算法。 以下证明过程摘自维基百科: 即答案为 (n*n*n*n-6*n*n*n+23*n*n-18*n+24)/24 由于 0≤n≤2^31,需要高精度。 c++代码如下: # 阅读全文
摘要:
题目链接:Link Solution 废话不说,先贴代码..... #include<cstdio> #include<cstring> int n,m,maxd,cnt,sum; int FullSize[625],Size[625]; bool sti[65],in[625][65]; inli 阅读全文
摘要:
题目链接:Link Solution 令 \(x_i\) 表示从 \(a_1\) 到 \(a_{i-1}\) 中比 \(a_i\) 小的数的个数, \(y_i\) 表示从 \(a_{i+1}\) 到 \(a_n\) 中比 \(a_i\) 小的数的个数,则答案等于 $\sum_{k=1}^N x[i] 阅读全文
摘要:
题目链接:Link Solution 第一次写DLX,写篇题解纪念一下……o(* ̄▽ ̄*)o 这题是一个典型的精确覆盖问题,每一行、每一列、每一个小方格都要有对应的数字,因此可以直接套模型,详细解释见代码: #include<cstdio> #include<cstring> #include<ve 阅读全文
摘要:
题目链接:Link Solution 首先,先按列处理出所有合法的字母,按字典序排列。 注意!有可能会有相同的字母! 接下来,从左到右计算应该选那个字母(无解的情况预处理一下就行了) #include<iostream> #include<vector> #include<cstring> #inc 阅读全文
摘要:
题目链接:Link Solution 首先,用一个表来解决输入问题(也可以动态生成)。 通过观察我们可以发现:每一个字符中的“白洞洞”的个数都不一样,因此可以用dfs数出每一个黑的联通块(字符)中的白洞洞的个数,加以区分。 细节得特别注意,代码如下: #include<cstdio> #includ 阅读全文
摘要:
题目链接:Link Solution 做这题时我借鉴了某一大佬的博客:传送门。 在这里我就把原文解释一下(详见代码): #include<cstdio> #include<cstring> const int N=70; int n,cnt,tot,maxn,minn,tm[N]; bool ok; 阅读全文