Codeforces Round #707 Div.2
A - Alexey and Train
直接按题意模拟即可。
#include <bits/stdc++.h>
using namespace std;
#define pb emplace_back
#define MP make_pair
#define pii pair<int,int>
#define pll pair<ll,ll>
#define lson rt<<1
#define rson rt<<1|1
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-6;
const int MAXN = 1e3 +7;
int a[MAXN],b[MAXN],tmi[MAXN];
int n;
int main() {
int T;scanf("%d",&T);
while(T--) {
scanf("%d",&n);
for(int i = 1;i <= n;i ++) {
scanf("%d%d",&a[i],&b[i]);
}
for(int i = 1;i <= n;i ++) {
scanf("%d",&tmi[i]);
}
int st = a[1] + tmi[1];
int i = 1;
while(i < n) {
st += (b[i] - a[i] + 1) / 2;
// cout<<st<<"***\n";
if(st >= b[i]) {
st += a[i+1] - b[i] + tmi[i+1];
i++;
}
else {
st = b[i];
st += a[i+1] - b[i] + tmi[i+1];
i++;
}
}
printf("%d\n",st);
}
return 0;
}
B - Napoleon Cake
模拟一个差分操作即可。注意当前位置滴上的奶油层数是可能大于当前位置的,所以做个越界检查需要。
#include <bits/stdc++.h>
using namespace std;
#define pb emplace_back
#define MP make_pair
#define pii pair<int,int>
#define pll pair<ll,ll>
#define lson rt<<1
#define rson rt<<1|1
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-6;
const int MAXN = 2e5 + 100;
int n,a[MAXN];
ll d[MAXN];
// int ans[MAXN];
int main() {
int T;scanf("%d",&T);
while(T--) {
scanf("%d",&n);
for(int i = 1;i <= n;i ++) scanf("%d",&a[i]);
for(int i = 1;i <= n;i ++) {
int l = max(1,i - a[i] + 1),r = i + 1;
d[l]++;
d[r]--;
}
for(int i = 1;i <= n;i ++) {
d[i] += d[i - 1];
}
for(int i = 1;i <= n;i ++) {
if(d[i]) printf("1 ");
else printf("0 ");
}
puts("");
for(int i = 0;i <= n + 10;i ++) d[i] = 0;
}
return 0;
}
C - Going Home
题意:
给定你一个长度为n的数组a,然后问你能否找到四个不同的位置
x
,
y
,
z
,
w
x,y,z,w
x,y,z,w使得
a
x
+
a
y
=
a
z
+
a
w
a_x + a_y =a_z + a_w
ax+ay=az+aw,能的话输出YES,并且输出这个四个位置,多解输出任意一个即可,否则输出NO。
思路:
题目提到数据范围
a
i
≤
2.5
e
6
a_i \leq 2.5e6
ai≤2.5e6,一般题目中一些特殊的数据范围是肯定有用意的,我们转化一下把求和其实也就是求差,这样对于这个数据范围,一定是可以在规定范围内求解的。
其实有这样的结论,如果一个差值记录下来的点对超过了四组,那么这个差值必定有解。
证明:
假若四个点值对为
(
x
,
y
1
)
,
(
x
,
y
2
)
,
(
x
,
y
3
)
,
(
u
,
v
)
(x,y_1),(x,y_2),(x,y_3),(u,v)
(x,y1),(x,y2),(x,y3),(u,v),其实
u
和
v
u和v
u和v的取值可以是任意的,无论为什么,他们这个几个点都能保证组成四个下标不同的位置。
这样暴力枚举的做法其实就是
2.5
e
6
∗
4
=
9
e
6
2.5e6 * 4 = 9e6
2.5e6∗4=9e6的复杂度内保证了有解情况,故直接暴力即可。
有特殊数据范围的题目一定要多考虑能否从数据范围上来找到解www
#include <bits/stdc++.h>
using namespace std;
#define pb emplace_back
#define MP make_pair
#define pii pair<int,int>
#define pll pair<ll,ll>
#define lson rt<<1
#define rson rt<<1|1
typedef long long ll;
typedef double db;
const int INF = 0x3f3f3f3f;
const db eps = 1e-6;
int n,a[200010];
std::vector<pii>val[3000000];
int ans[7];
bool cmp(int x,int y){ return a[x] < a[y]; }
bool check(int x,int y,int z,int w) {
if(x == y || x == z || x == w || y == z || y == w || w == z) return false;
return true;
}
//做题一些特殊的数值范围 一般都是有用意的
//2.5e6 我们考虑枚举差值的话 其实差值不可能超过这个范围的
//所以大胆猜测n大到一定范围后一定是有解的 这样保证了直接暴力也没有问题 大数据会直接return 答案
int main() {
scanf("%d",&n);
for(int i = 1;i <= n;i ++) scanf("%d",&a[i]);
int fg = 0;
for(int i = 1;i <= n;i ++) {
for(int j = 1;j < i;j ++) {
int d = abs(a[i] - a[j]);
if(val[d].size()) {
ans[1] = val[d][0].first,ans[2] = val[d][0].second;
ans[3] = i,ans[4] = j;
if(!check(ans[1],ans[2],ans[3],ans[4])) continue;
sort(ans + 1,ans + 1 + 4,cmp);
printf("YES\n%d %d %d %d\n",ans[1],ans[4],ans[2],ans[3]);
fg = 1;
return 0;
}
else val[d].pb(MP(i,j));
}
}
if(!fg) puts("NO");
return 0;
}