Codeforces Round #340 (Div. 2) (A,B,C,D)
tags : Codeforces
在家的第一场。这场前四题水得可以,所以我懒得描述题意了,,,
A.Elephant
分析
从0到n米处,每次能走1,2,3,4,5米,问至少需要多少次移动。显而易见先走5米,然后最后一次不足5米时直接走到底。步数为n/5+(n%5)?1:0
。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <queue>
using namespace std;
#define MAXN (500000+100)
int main()
{
int n;
scanf("%d", &n);
int ans = n / 5;
if (n % 5!=0)
ans++;
printf("%d\n",ans);
return 0;
}
B.Chocolate
分析
划分后要求每块有且只有一颗坚果。通过观察可以发现,划分的地方应该是在两个1之间的空隙,因此我们只需要统计两个1之间的0的个数,分段相乘即可。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <queue>
using namespace std;
#define MAXN (500000+100)
int main()
{
int n;
scanf("%d", &n);
long long ans = 1;
int flag = 0;
int cnt = 0;
for (int i = 0; i < n; i++)
{
long long x;
scanf("%lld",&x);
if (flag)
{
if (x == 0)
cnt++;
else
{
ans *= cnt + 1;
cnt = 0;
}
}
else if (x == 1)
flag = 1;
}
if (flag)
printf("%lld\n", ans);
else
printf("0\n");
return 0;
}
C.Watering Flowers
分析
用两个最圆覆盖所有的点,求
r21+r22
的最小值。
点的数目最多只有2000,只需要暴力两个圆的半径即可(半径取圆心到某一点的距离)。
需要注意“圆心外只有一个点”和“只有一个圆”两种情况。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>
using namespace std;
#define MAXN (5000+100)
struct node
{
long long x, y;
}p[MAXN];
int main()
{
long long n, x1, y1, x2, y2;
long long mr1 = 0, mr2 = 0;
scanf("%lld%lld%lld%lld%lld", &n, &x1, &y1, &x2, &y2);
for (int i = 0; i < n; i++)
{
scanf("%lld%lld", &p[i].x, &p[i].y);
mr1 = max(mr1, (p[i].x - x1)*(p[i].x - x1) + (p[i].y - y1)*(p[i].y - y1));
mr2 = max(mr2, (p[i].x - x2)*(p[i].x - x2) + (p[i].y - y2)*(p[i].y - y2));
}
long long ans = -1;
long long maxr = -1;
for (int i = 0; i < n; i++)
{
maxr = -1;
long long r1 = (p[i].x - x1)*(p[i].x - x1) + (p[i].y - y1)*(p[i].y - y1);
for (int j = 0; j < n; j++)
{
long long tmp = (p[j].x - x1)*(p[j].x - x1) + (p[j].y - y1)*(p[j].y - y1);
if (tmp > r1)
{
maxr = max(maxr, (p[j].x - x2)*(p[j].x - x2) + (p[j].y - y2)*(p[j].y - y2));
}
}
if (maxr != -1 && (ans == -1 || maxr + r1 < ans))
{
ans = maxr + r1;
}
}
long long mr = min(mr1, mr2);
if (ans == -1)
ans = mr;
printf("%lld\n", min(mr, ans));
return 0;
}
D.Polyline
分析
用折线覆盖三个点,问折线中线段数目最小值。
只有三个点,随便枚举一下就好了。
1. 三个点在同一条线上,只需要一条线段。
2. 两点一线且另一点在这条线段方向上的投影在线段外,两条线段。
3. 其他情况,需要三条线段。
代码
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>
#include <algorithm>
#include <queue>
using namespace std;
#define MAXN (5000+100)
int main()
{
long long x1, x2, x3, y1, y2, y3;
scanf("%lld%lld", &x1, &y1);
scanf("%lld%lld", &x2, &y2);
scanf("%lld%lld", &x3, &y3);
if ((x1 == x2&&x2 == x3) || (y1 == y2&&y2 == y3))
printf("1\n");
else if (
(x1 == x2&&(y3 >= max(y1, y2) || y3 <= min(y1, y2))) ||
(x1 == x3&&(y2 >= max(y1, y3) || y2 <= min(y1, y3))) ||
(x2 == x3&&(y1 >= max(y3, y2) || y1 <= min(y3, y2))) ||
(y1 == y2&&(x3 >= max(x1, x2) || x3 <= min(x1, x2))) ||
(y1 == y3&&(x2 >= max(x1, x3) || x2 <= min(x1, x3))) ||
(y2 == y3&&(x1 >= max(x3, x2) || x1 <= min(x3, x2))) )
printf("2\n");
else
printf("3\n");
return 0;
}