Codeforces Global Round 3
题目链接:https://codeforces.com/contest/1148
当年我不会做这个B题,却把CD过了。这个E题想错了。
A - Another One Bites The Dust
题意:有x个"a",y个"b",z个"ab",求最长的一个连续两个字符都不相同的字符串。
题解:肯定是先把z全部用了,易知'a'的数量和'b'的数量的相差不能超过1。
*B - Born This Way
这个题感觉不简单,没想到是1700难度的。
题意:要从A坐飞机中转B再到达C。A有n种航班飞到B,起飞时间分别是ai,飞行时间都是ta。B有m种航班飞到C,起飞时间分别是bj,飞行时间都是tb。取消不超过k种航班,使得最早的到达C的时间最迟。
题解:一开始想着贪心,但是怎么知道要使得这个B航班失效,是直接把他取消还是把能到他的A航班都取消呢?这个不能贪心。但是观察一段时间之后会发现,A航班总是取消最早的连续x种是最好的,因为假如也是取消x种,假如不是最早的连续x种,那么后面的就白白浪费取消的次数。然后又可以惊人的发现,枚举x之后,再取消第一个没有被取消的A航班能接上的接下来的k-x种B航班,就是最优的。也就是说是贪心取消掉最早的A航班,然后贪心取消掉剩下的有用的B航班里面最早的。
枚举这个x,然后双指针推一下。
不要溢出。
ll a[200005];
ll b[200005];
void TestCase() {
int n, m, k;
ll ta, tb;
scanf("%d%d%lld%lld%d", &n, &m, &ta, &tb, &k);
for(int i = 1; i <= n; ++i)
scanf("%lld", &a[i]);
for(int j = 1; j <= m; ++j)
scanf("%lld", &b[j]);
if(k >= n || k >= m) {
puts("-1");
return;
}
ll ans = 0;
int curj = 1;
//由于下面是枚举取消A航班的数量,所以上界是k+1,对应全部取消,易知a[k+1]一定存在
for(int i = 1; i <= k + 1; ++i) {
//取消掉前面的前i-1种A航班
while(curj <= m && a[i] + ta > b[curj]) {
//双指针找到第i种A航班能使用的第1个B航班,记为curj
++curj;
}
int t = k - (i - 1);
//若剩余的B航班可以全部取消,输出-1
if((m - curj + 1) <= t) {
puts("-1");
return;
}
//取消[curj,curj+t-1]的B航班
ans = max(ans, b[curj + t] + tb);
}
printf("%lld\n", ans);
}
C - Crazy Diamond
这个题也比较有想法。
题意:给一个n个数的排列,n是偶数,使用不超过5n次交换,给这个数组排序,要求每次交换的时候,选择的两个下标(i,j),满足2|i-j|>=n,换言之就是两个要隔得足够远,至少要隔半个数列的长度。
题解:这样看见“半个数列的长度”,就想到可以充分利用第1个元素和第n个元素来搞事,易知前半区间[1,n/2]的都可以和第n个元素交换,后半区间[n/2+1,n]的都可以和第1个元素交换。
先写一个交换函数,这样就不怕搞错了。
void myswap(int x, int y) {
swap(a[x], a[y]);
swap(pos[a[x]], pos[a[y]]);
ans[++atop] = {x, y};
}
每次调整第i个元素的时候,都满足前i-1个元素复位。
那么设数字i的位置为x,若2|x-i|>=n,就可以直接交换。
否则就要借助一些外力了。
以n=8为例:
1、若i<=n/2,且x>n/2:
由于他们离得比较近,所以i不会是1,x也不会是n
1.i.x..n
先交换(x,1)
x.i.1..n
再交换(1,n)
n.i.1..x
再交换(i,n)
n.x.1..i
再交换(x,1)
1.x.n..i
这样就完成了任务,至于n和i是怎么样的,就留给后面的迭代自己处理。
2、若i<=n/2,且x<=n/2:
1.ix...n
先交换(i,n)
1.nx...i
再交换(x,n)
1.ni...x
再交换(i,n)
1.xi...n
又完成了任务。
否则,两者都必定在右半区间,把上面的第2种情况反过来就可。
int n;
int a[300005];
int pos[300005];
pii ans[1500005];
int atop;
void myswap(int x, int y) {
swap(a[x], a[y]);
swap(pos[a[x]], pos[a[y]]);
ans[++atop] = {x, y};
}
void solve(int i) {
if(a[i] == i)
return;
int x = pos[i];
if(2 * (x - i) >= n) {
myswap(x, i);
return;
}
if(i <= n / 2) {
if(x > n / 2) {
myswap(x, 1);
myswap(1, n);
myswap(n, i);
myswap(x, 1);
return;
} else {
myswap(i, n);
myswap(x, n);
myswap(i, n);
return;
}
} else {
myswap(i, 1);
myswap(x, 1);
myswap(i, 1);
return;
}
}
void TestCase() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
pos[a[i]] = i;
}
atop = 0;
for(int i = 1; i <= n; ++i)
solve(i);
printf("%d\n", atop);
for(int i = 1; i <= atop; ++i)
printf("%d %d\n", ans[i].first, ans[i].second);
return;
}
原文地址:https://www.cnblogs.com/KisekiPurin2019/p/12572742.html
- C++STL之map的基本操作
- android EventBus 3.0使用指南
- C++ STL之deque的基本操作
- Android 四种常见的线程池
- Java注解
- C++ STL之排序算法
- Android View架构总结
- 怎样用Python给宝宝取个好名字?
- 字符串处理技巧
- SwipeRefreshLayout下拉刷新组件
- 使用数字进行字符遍历
- 技术分享:杂谈如何绕过WAF(Web应用防火墙)
- 模拟Executor策略的实现如何控制执行顺序?怎么限制最大同时开启线程的个数?为什么要有一个线程来将结束的线程移除出执行区?转移线程的时候要判断线程是否为空遍历线程的容器会抛出ConcurrentM
- ViewPager快速实现引导页
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【python-树的宽度遍历】二叉树的反向层次遍历
- 基于TypeScript封装Axios笔记(二)
- redis高性能数据结构之有序集
- spring之通过静态工厂方法配置Bean
- 【python-leetcode107-树的宽度遍历】二叉树的层次遍历Ⅱ
- spring之通过注解方式配置Bean(一)
- React17新特性:启发式更新算法
- spring之通过FactoryBean配置Bean
- 谱聚类的python实现
- 基于TypeScript封装Axios笔记(三)
- hadoop伪分布式之启动HDFS并运行MR程序(WordCount)
- 细品Reids的HyperLogLog数据结构
- 布隆过滤器与缓存击穿
- spring之通过注解方式配置Bean(二)
- 【python-leetcode103-树的宽度遍历】二叉树的锯齿形层次遍历