2019DX#5
| Solved | Pro.ID | Title | Ratio(Accepted / Submitted) |
| 1001 | fraction 辗转相除 | 4.17%(7/168) | |
| ok | 1002 | three arrays 字典树+贪心 | 12.69%(76/599) |
| 1003 | geometric problem | 1.59%(1/63) | |
![]() |
1004 | equation | 20.65%(310/1501) |
![]() |
1005 | permutation 1 | 24.77%(407/1643) |
![]() |
1006 | string matching | 23.12%(724/3131) |
![]() |
1007 | permutation 2 | 47.19%(688/1458) |
| ok | 1008 | line symmetric 计算几何 | 1.87%(11/588) |
| 1009 | discrete logarithm problem 离散对数 | 18.42%(7/38) | |
| 1010 | find hidden array 贪心 | 6.25%(2/32) |
1002 three arrays
题意
给定两个长度为1e5的数组$a_1,a_2,...a_n$、$b_1,b_2,...b_n$,重新排列,使得$a_i \oplus b_i $的字典序最小。
$0 \le a_i , b_i < 2^{30}$
思路
对a数组和b数组建立两个字典树,然后遍历n次这两个字典树,每次两个指针分别从两颗字典树移动,能同时向0走就走,能同时向1走就向1走,每次走到底层后就是一个答案。
// #pragma GCC optimize(2)
// #pragma GCC optimize(3)
// #pragma GCC optimize(4)
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cassert>
// #include<bits/extc++.h>
// using namespace __gnu_pbds;
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a) typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll; const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f;
const int mod = ; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} /**********showtime************/
const int maxn = 1e5+;
int a[maxn],b[maxn];
int tot[],rt[];
int bz[];
struct node{
int ch[];
int fa;
int sz;
void init(int f) {
ch[] = ch[] = ;
fa = f;
sz = ;
}
}tree[][maxn * ];
int shu[]; void add(int p, int len, int flag) {
if(len == ){
tree[flag][p].sz++;
return;
} if(tree[flag][p].ch[shu[len]] == )
{
tree[flag][p].ch[shu[len]] = ++ tot[flag];
tree[flag][tot[flag]].init(p);
}
int nx = tree[flag][p].ch[shu[len]];
add(nx, len-, flag);
int lc = tree[flag][p].ch[];
int rc = tree[flag][p].ch[];
tree[flag][p].sz = tree[flag][lc].sz + tree[flag][rc].sz;
}
void insert(int val, int flag) {
int len = ;
for(int i=; i<=; i++) shu[++len] = val % , val /= ;
add(rt[flag], , flag);
}
void display(int rt, int flag) {
if(rt == ) return ;
// cout<<tree[flag][rt].sz<<endl;
display(tree[flag][rt].ch[], flag);
display(tree[flag][rt].ch[], flag);
}
vector<int>vec;
void find(int a, int b, int cen, int val) {
if(cen == ) {
vec.pb(val);
tree[][a].sz--;
tree[][b].sz--;
return;
}
if(tree[][ tree[][a].ch[] ].sz && tree[][ tree[][b].ch[]].sz ) {
find(tree[][a].ch[], tree[][b].ch[], cen-, val);
}
else if(tree[][ tree[][a].ch[] ].sz && tree[][ tree[][b].ch[]].sz) {
find(tree[][a].ch[], tree[][b].ch[], cen-, val);
}
else if(tree[][tree[][a].ch[]].sz && tree[][ tree[][b].ch[]].sz){
find(tree[][a].ch[], tree[][b].ch[], cen-, val + bz[cen-]);
}
else {
find(tree[][a].ch[], tree[][b].ch[], cen-, val + bz[cen-]);
} tree[][a].sz = tree[][tree[][a].ch[]].sz + tree[][tree[][a].ch[]].sz;
tree[][b].sz = tree[][tree[][b].ch[]].sz + tree[][tree[][b].ch[]].sz; }
int main(){
int T; scanf("%d", &T);
bz[] = ;
for(int i=; i<=; i++) bz[i] = * bz[i-];
while(T--) {
tot[] = tot[] = ;
rt[] = ++tot[];
tree[][rt[]].init();
rt[] = ++tot[];
tree[][rt[]].init(); int n; scanf("%d", &n);
for(int i=; i<=n; i++) scanf("%d", &a[i]), insert(a[i], );
for(int i=; i<=n; i++) scanf("%d", &b[i]), insert(b[i], ); vec.clear();
for(int i=; i<=n; i++) {
find(rt[], rt[], , );
}
sort(vec.begin(), vec.end());
for(int i=; i<vec.size() - ; i++) printf("%d ", vec[i]);
printf("%d\n", vec[vec.size() - ]);
// display(rt[0], 0);
}
return ;
}
1008 line symmetric
题意
给定一个多边形,定点最多有1000个,在最多移动一个点的情况下,此多边形是否能成为轴对称图形,变换后图形要保证是简单多边形。
思路
1)枚举相邻点,和间隔为2的两个点,令他们的中垂线为对称轴,判断是否可行。
2)注意点是,一个点如果在枚举的对称轴上,那么就是不可行的。
3)如果两个点如果在对称轴的两边,且要相互交换位子,那么这也是不可行的。
// #pragma GCC optimize(2)
// #pragma GCC optimize(3)
// #pragma GCC optimize(4)
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cassert>
// #include<bits/extc++.h>
// using namespace __gnu_pbds;
using namespace std;
#define pb push_back
#define fi first
#define se second
#define debug(x) cerr<<#x << " := " << x << endl;
#define bug cerr<<"-----------------------"<<endl;
#define FOR(a, b, c) for(int a = b; a <= c; ++ a) typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll; const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f;
const int mod = ; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} /**********showtime************/
const int maxn = 1e3+;
pii po[maxn];
int n;
bool dc(int le, int ri, pii m, pii k){
// 判垂直
int a = (po[ri].se - po[le].se) * k.se;
int b = (po[ri].fi - po[le].fi) * k.fi;
if(a != -b) return false; // 判中点
pii mid;
mid.fi = (po[le].fi + po[ri].fi) / ;
mid.se = (po[le].se + po[ri].se) / ; if(k.fi == ) {
return mid.fi == m.fi;
}
a = mid.se * k.fi;
b = k.se * mid.fi + m.se * k.fi - k.se * m.fi;
return a == b;
} bool gao(int p1, int p2, pii m, pii k) {
if(k.fi == ) {
return (po[p1].fi - m.fi) * (po[p2].fi - m.fi) <= ;
}
int tmp1 = po[p1].se * k.fi - k.se * po[p1].fi + m.se * k.fi- k.se * m.fi;
int tmp2 = po[p2].se * k.fi - k.se * po[p2].fi + m.se * k.fi- k.se * m.fi;
return 1ll*tmp1 * tmp2 <= ;
}
bool check(int le, int ri) {
int sl = le, sr = ri;
pii m, k; m.fi = (po[le].fi + po[ri].fi) / ;
m.se = (po[le].se + po[ri].se) / ;
k.fi = po[ri].se - po[le].se;
k.se = -*(po[ri].fi - po[le].fi);
int cnt = ; for(int i=; i <= (n+) / ; i++){
if(gao(sl, le, m, k) && gao(sr, ri, m, k) ) return false;
if(dc(le, ri, m, k) == ) cnt++; ri++; if(ri == n+) ri = ;
le--; if(le == ) le = n;
}
return cnt <= ;
} bool check1(int le, int ri, int mid) {
int sl = le, sr = ri;
pii m, k;
m.fi = (po[le].fi + po[ri].fi) / ;
m.se = (po[le].se + po[ri].se) / ;
k.fi = po[ri].se - po[le].se;
k.se = -*(po[ri].fi - po[le].fi);
// cout<<m.fi<<" , " << m.se<<endl;
// cout<<k.fi<<" , " << k.se<<endl;
int cnt = ;
for(int i=; i <= n / ; i++){
if(gao(sl, le, m, k) && gao(sr, ri, m, k)) return false;
if(dc(le, ri, m, k) == ) cnt++; ri++; if(ri == n+) ri = ;
le--; if(le == ) le = n;
} if(dc(mid, mid, m, k) == ) cnt++;
return cnt <= ;
}
int main(){
int T; scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i=; i<=n; i++) {
scanf("%d%d", &po[i].fi, &po[i].se);
po[i].fi *= ;
po[i].se *= ;
}
if(n <= ) {
puts("Y");
continue;
}
int flag = ; for(int i=; i<=n; i++) {
int nx = (i + ) ; if(nx == n+) nx = ;
int la = i - ; if(!la) la = n;
int mid = i;
if(check1(la,nx, mid)) flag = ;
}
for(int i=; i<=n; i++) {
int cur = i;
int nx = i + ; if(nx == n+) nx = ;
if(check(cur, nx)) flag = ;
} if(flag) puts("Y");
else puts("N");
}
return ;
}
/*
5
-100 -100
0 0
-100 100
1 0
100 1
*/
2019DX#5的更多相关文章
- 2019DX#10
Solved Pro.ID Title Ratio(Accepted / Submitted) 1001 Minimum Spanning Trees 22.22%(2/9) 1002 Lin ...
- 2019dx#9
Solved Pro.ID Title Ratio(Accepted / Submitted) 1001 Rikka with Quicksort 25.85%(38/147) 1002 Ri ...
- 2019DX#8
Solved Pro.ID Title Ratio(Accepted / Submitted) 1001 Acesrc and Cube Hypernet 7.32%(3/41) 1002 A ...
- 2019dx#7
Solved Pro.ID Title Ratio(Accepted / Submitted) 1001 A + B = C 10.48%(301/2872) 1002 Bracket Seq ...
- 2019DX#6
Solved Pro.ID Title Ratio(Accepted / Submitted) 1001 Salty Fish 16.28%(7/43) OK 1002 Nonsense Tim ...
- 2019dx#4
Solved Pro.ID Title Ratio(Accepted / Submitted) 1001 AND Minimum Spanning Tree 31.75%(1018/3206) ...
- 2019DX#3
Solved Pro.ID Title Ratio(Accepted / Submitted) 1001 Azshara's deep sea 凸包 6.67%(6/90)
- 2019DX#2
Solved Pro.ID Title Ratio(Accepted / Submitted) 1001 Another Chess Problem 8.33%(1/12) 1002 Beau ...
- 2019DX#1
1001 Blank 题意 有一个长度为n(n<=100)的位子,填入四种颜色,有m个限制,某个区间的颜色个数要恰好等于x个.问颜色个数的方案数. 思路 DP 四维的DP,利用滚动数组优化一维空 ...
随机推荐
- @Validated和@Valid的区别?校验级联属性(内部类)
每篇一句 NBA里有两大笑话:一是科比没天赋,二是詹姆斯没技术 相关阅读 [小家Java]深入了解数据校验:Java Bean Validation 2.0(JSR303.JSR349.JSR380) ...
- Nginx 的简单使用 (IIS,Asp.Net)
Nginx 的一些常见功能(windows,AspNet ,IIS) 下载 官方网站:https://nginx.org/en/download.html 下载,解压缩是这个样子 启动: 启动方式有两 ...
- codeforces 327 B. Hungry Sequence
题目链接 题目就是让你输出n个数的序列,要保证该序列是递增的,并且第i个数的前面不能保护它的约数,我直接先对前100000的素数打表,然后输出前n个,so easy. //cf 191 B #incl ...
- 堆排序(实现c++)
堆可以看作是一个完全二叉树,分为大顶堆和小顶堆,本文我们以大顶堆为例来实现堆排序. (1)建堆 先把给定的序列转换成一棵完全二叉树,然后逐步对其调整使其每个结点的值都大于其两个子结点的值,因此我们需要 ...
- 【0806 | Day 9】三张图带你了解数据类型分类和Python深浅拷贝
一.数据类型分类 二.Python深浅拷贝
- Spring 2017 Assignments1
一.作业要求 原版:http://cs231n.github.io/assignments2017/assignment1/ 翻译:http://www.mooc.ai/course/268/lear ...
- hadoop2.7之作业提交详解(下)
接着作业提交详解(上)继续写:在上一篇(hadoop2.7之作业提交详解(上))中已经讲到了YARNRunner.submitJob() [WordCount.main() -> Job.wai ...
- 【Isabella Message】 【SPOJ - ISAB】【模拟】【矩阵的旋转】
思路 题目链接 题意:题目中先给了一个N阶矩阵样子的字符,后给了一个mask,然后又给出你应该认识的一些单词,最后是让你输出最终字典序最小的一句话. 思路:根据题目要求模拟即可.这里会用到string ...
- PL/SQL 调用 JAVA代码
1.直接在 SQL Developer中写入代码 create or replace and compile java source named "HelloWorld" as p ...
- Python 類別 class 的繼承 Inheritance
既然 Python 是面向物件 Object Oriented 語言,它就有類別 Class 與物件 Object 的概念. 甚麼是類別 class ? 簡單講: 類別好比蓋房子的施工藍圖 Blue ...
