今天记录一下写过的有必要记录的题,算小结,本日任务重点在图形学。
Alice and Bob
题目大意:给定两堆石头,AB二人分别从一堆中取走不超过m个的k个石块,可以选择从另一堆取走s*k(s为任意自然数)个石头,最后无法取走者失败。(5000数据量)
解法:高级一点的博弈,四个循环将所有成功情况遍历出来即可得到答案。
Hash Function
题目大意:给定一组数S,给出这组数利用mod n进行哈希的哈希值,使得n最小。
解法:用NTT/FFT来加速你的求解过程。其他和搜索一样。还是看佬的码吧
GCD
题目大意:给定一组数字和一个容器,一个数字占用容器的一个位置,要求所有填满容器的组合的GCD值乘积。
解法:素数提取,利用素数筛提前计算素数,计算PhiM,利用杨辉三角和费马小定理/Phi算法来加速这个过程。
Stack
题目大意:给出段伪码(生成非严格上升子序列的长度),生成一段数据提取其中的片段交给做题人,要求还原一个满足此要求的数据。
Stk is an empty stack
for i = 1 to n :
while ( Stk is not empty ) and ( Stk's top > a[i] ) :
pop Stk
push a[i]
b[i]=Stk's size
解法:个人推荐使用记录每个数据所在位置,然后进行还原的类前缀数组的作法,好处是好看好理解。
#include <iostream> #include <cstdio> #include <vector> using namespace std; int main(){ int n,k; std::cin>>n>>k; std::vector<int> b(n); for(int i=0;i<k;i++){ int p,x; std::cin>>p>>x; p--; b[p]=x; } int cur=0; for(int i=0;i<n;i++){ cur++; if(b[i]>0){ if(b[i]>cur){ std::cout<<"-1\n"; return 0; } cur=b[i]; }else{ b[i]=cur; } } std::vector<int> cnt(n+1); std::vector<int> a(n); for(int i=0;i<n;i++){ cnt[b[i]]++; } for(int i=1;i<=n;i++){ cnt[i]+=cnt[i-1]; } for(int i=0;i<n;i++){ std::cout<<cnt[b[i]]--<<" \n"[i == n-1]; } return 0; }
Girl friend
阿波罗尼圆(球)的相较面积/体积如何求?
推荐:两圆相交到两球相交 - Chasssser - 博客园 (cnblogs.com)
和:阿波罗尼斯圆怎么用? - 知乎 (zhihu.com)
阿氏圆_百度百科 (baidu.com)
公式记得开double,这个图形学会用。
代码查看 (nowcoder.com)
清佬的代码推荐。