比赛总结
打得有点怂,这次div1题目比较水,我做了三题,不过比较坑的是,我第二题因为少了几个特判,wa了8次才ac,第三题因为看错题,wa了两次才ac
在正式和非正式选手里排名438名
在正式选手里排名306名
(做了三题,罚时太惨被一堆做2题的艹了。。。)
A. Exams
题目链接
http://codeforces.com/contest/480/problem/A
题目大意
某人要参加
n
场考试,第
思路
考试进行的顺序,一定是按照 ai 升序,即先考 ai 小的,再考 ai 大的。
但是每场考试是选 ai 天考还是 bi 天考呢?显然是尽量选 bi 天考,我们记录 last= 上一次考试的日期,若 bi>=last ,就选 bi 天考,否则就只能选 ai 天考了。由于 bi<ai ,而且之前预处理时,考试是按照 ai 为第一关键字升序, bi 为第二关键字升序,所以 ai 保证是大于等于 last 的。这样的做法是一定正确的
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 6000
using namespace std;
pair<int,int>pr[MAXN];
int n;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&pr[i].first,&pr[i].second);
sort(pr+1,pr+n+1);
int last=pr[1].second;
for(int i=2;i<=n;i++)
{
if(pr[i].second>=last) last=pr[i].second;
else last=pr[i].first;
}
printf("%d\n",last);
return 0;
}
B. Long Jumps
题目链接
http://codeforces.com/contest/480/problem/B
题目大意
给你一个长度为
L
、有
思路
显然,答案最多为2,如果已经存在了某两个刻度之间距离为
x
或
这个可以通过枚举刻度
a[i]
,然后二分判断是否存在
a[i]+x
和
a[i]+y
来解决
但是重点不在于此,而是一个特殊情况:有可能存在某两个已经存在的刻度,插入一个新的刻度后,就可以满足题目要求了。这个就需要特判了,具体看代码比较清楚吧
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 6000
using namespace std;
pair<int,int>pr[MAXN];
int n;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&pr[i].first,&pr[i].second);
sort(pr+1,pr+n+1);
int last=pr[1].second;
for(int i=2;i<=n;i++)
{
if(pr[i].second>=last) last=pr[i].second;
else last=pr[i].first;
}
printf("%d\n",last);
return 0;
}
C. Riding in a Lift
题目链接
http://codeforces.com/contest/480/problem/C
题目大意
一个
n
层摩天楼里,某个人初始在
思路
一个非常显然的DP思路:
设 dis=|x−b|−1 ,则 f[i][j] 可以转移到 f[i+1][max{1,j−dis}] 到 f[i+1][min{n,j+dis}] ( f[i+1][j] 除外!)
这样DP的复杂度为 O(n3) ,可以考虑通过优化贡献答案的那部分来降维。
我们知道,给一个序列不断进行区间加的操作,可以维护一个数组a[]
a[]
,每次区间[L,R]
[L,R]
加val
val
时,让
a[L]+=val
,
a[R+1]+=val
,最后通过求前缀和即可得到若干次操作后的序列,这样操作,每次是
O(1)
的,就能在DP的区间更新答案步骤里做到降维了,每次枚举完某个
i
的所有
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAXN 6000
using namespace std;
pair<int,int>pr[MAXN];
int n;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&pr[i].first,&pr[i].second);
sort(pr+1,pr+n+1);
int last=pr[1].second;
for(int i=2;i<=n;i++)
{
if(pr[i].second>=last) last=pr[i].second;
else last=pr[i].first;
}
printf("%d\n",last);
return 0;
}