CCPC-Wannafly Winter Camp Day2 (Div2, onsite)
Class
$A_i = a \cdot i \% n$
有 $A_i = k \cdot gcd(a, n)$
证明:
$A_0 = 0, A_x = x \cdot a - y \cdot n$
$令 d = gcd(a, n)$
$A_x \% d = (x \cdot a \% d - y \cdot n \% d) \% d = 0$ 得证
循环节为$\frac {n}{gcd(a, n)}$
Replay
Dup4:
- 自闭了,啥都不会,想开一道无人做的字符串,喵喵喵?
- 总是陷入思维的泥浆,爬不出来,T那么大,怎么就想不到预处理呢
X:
- 成功晋升码农
- 第三次忘记预处理是个啥,最后全靠队友一波rush
- 日常开局血崩,这口锅必须要背
Solution
A: Erase Numbers II
思路:
$n^2 暴力 注意最大的那项会爆 long\; long 但不会爆 unsigned \;long \;long$
#include<bits/stdc++.h> using namespace std; typedef unsigned long long ull;
const int maxn = 1e5 + ; int n;
ull arr[maxn];
ull len[maxn]; int main()
{
int t;
scanf("%d", &t);
for(int cas = ; cas <= t; ++cas)
{
printf("Case #%d: ", cas);
scanf("%d", &n);
for(int i = ; i <= n; ++i)
{
scanf("%llu", arr + i);
len[i] = ;
ull x = arr[i];
while(x)
{
len[i] *= ;
x /= ;
}
}
ull ans = ;
for(int i = ; i <= n; ++i)
{
for(int j = i + ; j <= n; ++j)
{
ans = max(ans, arr[i] * len[j] + arr[j]);
}
}
printf("%llu\n", ans);
}
return ;
}
B: Erase Numbers I
思路:
$将删除两个数当做两次操作$
$每次操作删除剩余串中长度最小$
$先O(n)扫一遍,如果找到一个长度最小并且字典序小于后一位的,即可直接上出,并且保证了最优$
$如果第一遍扫没找到合适的, 就从后往前找到第一个长度最小的删除$
$做两遍即可$
#include<bits/stdc++.h> using namespace std; const int INF = 0x3f3f3f3f;
const int maxn = 1e4 + ; struct node{
char str[];
int len;
int flag;
}arr[maxn]; int n; int main()
{
int t;
scanf("%d", &t);
for(int cas = ; cas <= t; ++cas)
{
printf("Case #%d: ", cas);
scanf("%d", &n);
for(int i = ; i <= n; ++i)
{
scanf("%s", arr[i].str);
arr[i].len = strlen(arr[i].str);
arr[i].flag = ;
}
int pos1 = -, pos2 = -;
int Min = INF;
for(int i = ; i <= n; ++i) if(!arr[i].flag) Min = min(Min, arr[i].len);
for(int i = ; i <= n; ++i)
{
if(arr[i].flag) continue;
if(Min != arr[i].len) continue;
int j = i + ;
while(arr[j].flag && j <= n) ++j;
if(j <= n)
{
if(strcmp(arr[i].str, arr[j].str) < )
{
pos1 = i;
arr[i].flag = ;
break;
}
}
}
if(pos1 == -)
{
for(int i = n; i >= ; --i)
{
if(arr[i].flag) continue;
if(arr[i].len == Min)
{
arr[i].flag = ;
pos1 = i;
break;
}
}
}
Min = INF;
for(int i = ; i <= n; ++i) if(!arr[i].flag) Min = min(Min, arr[i].len);
for(int i = ; i <= n; ++i)
{
if(arr[i].flag) continue;
if(Min != arr[i].len) continue;
int j = i + ;
while(arr[j].flag && j <= n) ++j;
if(j <= n)
{
if(strcmp(arr[i].str, arr[j].str) < )
{
pos2 = i;
arr[i].flag = ;
break;
}
}
}
if(pos2 == -)
{
for(int i = n; i >= ; --i)
{
if(arr[i].flag) continue;
if(arr[i].len == Min)
{
arr[i].flag = ;
pos2 = i;
break;
}
}
}
for(int i = ; i <= n; ++i) if(!arr[i].flag) printf("%s", arr[i].str);
puts("");
}
return ;
}
H: Cosmic Cleaner
思路:
$球缺体积$
$用一个平面截去一个球所得部分叫球缺$
$球缺面积 = 2 \cdot \pi h$
$球缺体积 = \pi \cdot h^2 \cdot (R - \frac{h}{3})$
$球缺质心:匀质球缺的质心位于它的中轴线上,并且与底面的距离为$
$C = \frac{(4\cdot R - h) \cdot h}{12 \cdot R - 4 \cdot h} = \frac{(d^2 + 2\cdot h^2) \cdot h}{3\cdot d^2 + 4\cdot h^2}$
$然后分分类 搞一搞,就好了$
#include<bits/stdc++.h> using namespace std; const double eps = 1e-;
const double PI = acos(-1.0);
const int maxn = 1e2 + ; int sgn(double x)
{
if(fabs(x) < eps) return ;
else return x > ? : -;
} struct node{
double x, y, z, r;
node(){}
node(double x, double y, double z, double r): x(x), y(y), z(z), r(r){}
}O, P[maxn]; double getdis(node p1, node p2)
{
double res = (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y) + (p1.z - p2.z) * (p1.z - p2.z);
res = sqrt(res);
return res;
} int n; int main()
{
int t;
scanf("%d", &t);
for(int cas = ; cas <= t; ++cas)
{
printf("Case #%d: ", cas);
scanf("%d", &n);
for(int i = ; i <= n; ++i)
{
scanf("%lf %lf %lf %lf", &P[i].x, &P[i].y, &P[i].z, &P[i].r);
}
scanf("%lf %lf %lf %lf", &O.x, &O.y, &O.z, &O.r);
double ans = ;
for(int i = ; i <= n; ++i)
{
double dis = getdis(O, P[i]);
double tmp = dis - O.r - P[i].r;
//out
if(sgn(tmp) > )
{
continue;
} //in
if(sgn(dis + P[i].r - O.r) <= )
{
double tmp1 = 4.0 / 3.0 * PI * P[i].r * P[i].r * P[i].r;
ans += tmp1;
continue;
} //part1
double r1 = O.r, r2 = P[i].r; double r0 = (r1 * r1 + dis * dis - r2 * r2) / (2.0 * dis);
double h1 = r1 - r0; ans += PI * h1 * h1 * (r1 - h1 / 3.0); //part2
r0 = (r2 * r2 + dis * dis - r1 * r1) / (2.0 * dis);
double h2 = r2 - r0;
ans += PI * h2 * h2 * (r2 - h2 / 3.0);
}
printf("%.10f\n", ans);
}
return ;
}
K: Sticks
思路:
将$l_i排序,接着n^3处理出合法的三角形关系,然后枚举三角形关系$
$注意不要重复枚举,但是暴力枚举常数还是太大$
$考虑一条剪枝,如果有一个三角关系,令其为a_1, a_2, a_3$
$如果存在 a_x >= a_3 和 a_1 以及 a_2 也同样满足大小关系,那么这个三角关系不用枚举$
$因为我们是从小到大枚举,在二三层循环当中枚举到的点的长度肯定比第一层的要大$
$那么对于a_x >= a_3 将a_x留在后面的三角关系中会使得答案更优$
然后就过了..
但实际上有一种更为科学的?方法
考虑合法的不重复的四对三角关系只有$\frac {C_{12}^3 \cdot C_{9}^3 \cdot C_6^3 }{4!}$
只有$15400 如果能够预处理出来,再暴力枚举的时间复杂度是对的$
考虑如何预处理
显然有个$O(220^4)的方法$
那么我们考虑能否优化掉第四维的$220$
$其实前三个三角关系确定了,第四个自然确定了,但是我们需要去重啊$
先考虑不重不漏的枚举三角关系 从小到大,并且每一个三角关系都有唯一编号
$用 Hash[][][] 进行Hash$
这样就可以$O(1)得到剩下的那个三角关系的编号,考虑编号和前三个三角关系编号的大小$
如果小了,那么肯定重复了
#include <bits/stdc++.h>
using namespace std; #define N 15
int t, l[N], vis[N];
struct node
{
int x, y, z;
node () {}
node (int x, int y, int z) : x(x), y(y), z(z) {}
}; vector <node> v;
vector <int> res;
int Stack[], top; bool ok(int x, int y, int z)
{
if (x + y > z && x + z > y && y + z > x) return ;
return ;
} bool used(node a)
{
if (!vis[a.x] && !vis[a.y] && !vis[a.z]) return ;
return ;
} void work(int i)
{
Stack[++top] = v[i].x;
Stack[++top] = v[i].y;
Stack[++top] = v[i].z;
vis[v[i].x] = ;
vis[v[i].y] = ;
vis[v[i].z] = ;
} void clear(int i)
{
top -= ;
vis[v[i].x] = ;
vis[v[i].y] = ;
vis[v[i].z] = ;
} void add()
{
if (top > res.size())
{
res.clear();
for (int o = ; o <= top; ++o) res.push_back(Stack[o]);
}
} void solve()
{
int m = v.size();
for (int i = ; i < m; ++i) if (i == || !(v[i].x == v[i - ].x && v[i].y == v[i - ].y))
{
work(i); add();
for (int j = i + ; j < m; ++j) if (!used(v[j]))
{
work(j); add();
for (int k = j + ; k < m; ++k) if (!used(v[k]))
{
work(k); add();
int a[] = {}, cnt = ;
for (int o = ; o <= ; ++o) if (!vis[o])
a[cnt++] = o;
if (ok(l[a[]], l[a[]], l[a[]]))
{
for (int o = ; o < ; ++o) Stack[++top] = a[o];
add();
return;
}
clear(k);
}
clear(j);
}
clear(i);
}
} int main()
{
scanf("%d", &t);
for (int kase = ; kase <= t; ++kase)
{
printf("Case #%d: ", kase); top = ; res.clear();
memset(vis, , sizeof vis);
for (int i = ; i <= ; ++i) scanf("%d", l + i);
sort(l + , l + );
v.clear();
for (int i = ; i <= ; ++i) for (int j = i + ; j <= ; ++j) for (int k = j + ; k <= ; ++k) if (ok(l[i], l[j], l[k]))
v.push_back(node(i, j, k));
solve();
int k = res.size() / ;
printf("%d\n", k);
for (int i = , len = res.size(); i < len; ++i) printf("%d%c", l[res[i]], " \n"[(i + ) % == ]);
}
return ;
}
#include <bits/stdc++.h>
using namespace std; #define N 15
#define M 200100
int t, n, l[N], vis[N]; struct node
{
int a[];
node () {}
node (int x, int y, int z)
{
a[] = x;
a[] = y;
a[] = z;
}
bool ok()
{
if (l[a[]] + l[a[]] > l[a[]] && l[a[]] + l[a[]] > l[a[]] && l[a[]] + l[a[]] > l[a[]]) return ;
return ;
}
void out()
{
for (int i = ; i < ; ++i) printf("%d%c", l[a[i]], " \n"[i == ]);
}
}; vector <node> vec;
node que[M][];
node Stack[]; int top;
int Hash[][][]; void used(node x) { for (int i = ; i < ; ++i) vis[x.a[i]] = ; }
void clear(node x) { for (int i = ; i < ; ++i) vis[x.a[i]] = ; --top; }
bool notused(node x) { for (int i = ; i < ; ++i) if (vis[x.a[i]]) return false; return true; } void init()
{
int m = ;
for (int i = ; i <= ; ++i) for (int j = i + ; j <= ; ++j) for (int k = j + ; k <= ; ++k)
{
vec.push_back(node(i, j, k));
Hash[i][j][k] = m;
++m;
}
n = ; top = ;
for (int i = ; i < m; ++i)
{
Stack[++top] = vec[i];
used(vec[i]);
for (int j = i + ; j < m; ++j) if (notused(vec[j]))
{
Stack[++top] = vec[j];
used(vec[j]);
for (int k = j + ; k < m; ++k) if (notused(vec[k]))
{
Stack[++top] = vec[k];
used(vec[k]);
node tmp; int cnt = ;
for (int o = ; o <= ; ++o) if (!vis[o])
tmp.a[cnt++] = o;
if (Hash[tmp.a[]][tmp.a[]][tmp.a[]] > k)
{
Stack[++top] = tmp;
++n;
for (int o = ; o <= top; ++o) que[n][o] = Stack[o];
--top;
}
clear(vec[k]);
}
clear(vec[j]);
}
clear(vec[i]);
}
} int main()
{
init();
scanf("%d", &t);
for (int kase = ; kase <= t; ++kase)
{
printf("Case #%d: ", kase);
for (int i = ; i <= ; ++i) scanf("%d", l + i);
vector <node> res, tmp;
for (int i = ; i <= n; ++i)
{
tmp.clear();
for (int j = ; j <= ; ++j) if (que[i][j].ok())
tmp.push_back(que[i][j]);
if (tmp.size() > res.size()) res = tmp;
if (res.size() == ) break;
}
int k = res.size();
printf("%d\n", k);
for (int i = ; i < k; ++i) res[i].out();
}
return ;
}
CCPC-Wannafly Winter Camp Day2 (Div2, onsite)的更多相关文章
- 2019 CCPC-Wannafly Winter Camp Day2(Div2, onsite)
solve 4/11 A Erase Numbers II Code:KK Thinking :KK 用ans表示当前最优答案,maxx表示遍历到的最大数字,一开始ans肯定等于a[ 1 ]+a[ 2 ...
- 2020 CCPC Wannafly Winter Camp Day1 C. 染色图
2020 CCPC Wannafly Winter Camp Day1 C. 染色图 定义一张无向图 G=⟨V,E⟩ 是 k 可染色的当且仅当存在函数 f:V↦{1,2,⋯,k} 满足对于 G 中的任 ...
- CCPC Wannafly Winter Camp Div2 部分题解
Day 1, Div 2, Prob. B - 吃豆豆 题目大意 wls有一个\(n\)行\(m\)列的棋盘,对于第\(i\)行第\(j\)列的格子,每过\(T[i][j]\)秒会在上面出现一个糖果, ...
- CCPC-Wannafly Winter Camp Day5 (Div2, onsite) Sorting(线段树)
题目链接 题意 对序列进行三种操作: 1.区间求和. 2.将区间小于等于$x$的数不改变相对顺序的前提下放到$x$左边,用同样规则将比$x$大的放到右边. 3.将区间大于$x$的数不改变相对顺序的前提 ...
- CCPC-Wannafly Winter Camp Day8 (Div2, onsite)
咕咕咕. camp补题. 传送门:https://www.zhixincode.com/contest/29/problems A.Aqours 题意:有一棵有根树,根节点为1,给出每个结点的父 ...
- CCPC-Wannafly Winter Camp Day3 (Div2, onsite)
Replay Dup4: 没想清楚就动手写? 写了两百行发现没用?想的还是不够仔细啊. 要有莽一莽的精神 X: 感觉今天没啥输出啊, 就推了个公式?抄了个板子, 然后就一直自闭A. 语文差,题目没理解 ...
- 2019 CCPC-Wannafly Winter Camp Day1 (Div2, onsite)
solve:4/11 补题:6/11 A 机器人 补题:zz 这是一道分类讨论的题目,有一个规律就是如果必须要从第一个区到第二个区,那么最多转区两次(1到2一次,2到1一次),然后分类讨论即可,只要细 ...
- 2019 CCPC-Wannafly Winter Camp Day7(Div2, onsite)
solve 6/11 补题: A.迷宫 Code:zz Thinking:zz kk 把每个节点的深度都处理出来,同一深度的点的冲突度为 (x-1),x为同层次点数减一. 然后冲突度不断下传(冲突度为 ...
- Wannafly Winter Camp Day8(Div1,onsite) E题 Souls-like Game 线段树 矩阵乘法
目录 Catalog Solution: (有任何问题欢迎留言或私聊 && 欢迎交流讨论哦 Catalog @ Problem:传送门 Portal 原题目描述在最下面. 简单的 ...
随机推荐
- GIS-008-ArcGIS JS API 全图
//待服务加载完成后,设置视野范围到全图范围 layer.on('load', function () { var extent = map.getLayer(map.layerIds[0]).ful ...
- ftplib模块【python】
转自:http://www.cnblogs.com/kaituorensheng/p/4480512.html 函数释义 Python中默认安装的ftplib模块定义了FTP类,其中函数有限,可用来实 ...
- 【mysql】查看版本的四种方法
1:在终端下:mysql -V. 以下是代码片段: [test@login ~]$ mysql -V mysql Ver 14.7 Distrib 4.1.10a, for redhat-linux- ...
- ajax 跨域访问 :Access-Control-Allow-Origin
一说到ajax跨域.首先想到的就是jsonp . JSONP方法是一种非官方方法,而且这种方法只支持GET方式,不如POST方式安全. 即使使用jQuery的jsonp方法,type设为POST,也 ...
- LeetCode——Power of Two
Description: Given an integer, write a function to determine if it is a power of two. public class S ...
- swiper的延迟加载(非官网方法)
网上找的: https://github.com/nolimits4web/Swiper/issues/626 var tabsSwiper = new Swiper('#games-content' ...
- 【BZOJ2668】[cqoi2012]交换棋子 费用流
[BZOJ2668][cqoi2012]交换棋子 Description 有一个n行m列的黑白棋盘,你每次可以交换两个相邻格子(相邻是指有公共边或公共顶点)中的棋子,最终达到目标状态.要求第i行第j列 ...
- python webdriver中对不同下拉框通过文本值的选择
在自动化中python对下拉框的处理网上相对实例比较少,其它前辈写的教程中对下拉也仅仅是相对与教程来说的,比如下面: m=driver.find_element_by_id("Shippin ...
- git add -A和git add . 的区别
git add -A和 git add . git add -u在功能上看似很相近,但还是有所差别. git add . :他会监控工作区的状态树,使用它会把工作时的所有变化提交到暂存区,包括文件内容 ...
- postgresql----数据库表约束----UNIQUE
四.UNIQUE ---- 唯一约束 唯一键可以是单个字段,也可以是多个字段的组合,设置唯一约束后,INSERT或UPDATE时如果表中唯一键字段中已存在该数据,则拒绝该行数据的INSERT或UPDA ...