题目链接:点击打开链接
这次的比赛比较简单, 有些坑点, 主要是考思维的严密性。。。
比赛时做出了前4道, 都没有什么算法, 最后一道的通用解法是莫队算法, 现在还不会, 今天就补上。
终测挂了C,原来是漏了枚举第一个半径为0的情况, 太失误了。
A. Elephant
水题。
细节参见代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int mod = 1000000000 + 7;
const ll INF = 1000000000000000000+10000000;
const int maxn = 100;
int T,n,m,x;
ll l,r,k;
int main() {
scanf("%d",&x);
int ans = x / 5;
if(ans * 5 != x) ans++;
printf("%d\n",ans);
return 0;
}
B. Chocolate
注意全0的时候答案是0
细节参见代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int mod = 1000000000 + 7;
const int INF = 1000000000;
const int maxn = 100 + 10;
int T,n,m,a[maxn];
ll b[maxn];
int main() {
scanf("%d",&n);
bool ok = false;
for(int i=0;i<n;i++) {
scanf("%d",&a[i]);
if(a[i]) ok = true;
}
if(!ok) { printf("0\n"); return 0; }
int len = 0;
int l = -1, r;
for(int i=0;i<n;i++) {
if(a[i] == 1) {
if(l == -1) l = i;
else {
b[len++] = i - l;
l = i;
}
continue;
}
}
ll ans = 1;
for(int i=0;i<len;i++) {
ans *= b[i];
}
printf("%I64d\n",ans);
return 0;
}
C. Watering Flowers
思路:n^2枚举, 第一层枚举第一个值r^2,也就是0和其他所有点到喷泉的距离平方。 第二层再枚举一遍所有点,把所有不在第一个半径范围的点归给第二个喷泉, 然后每次更新最小值就行了。
细节参见代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int mod = 1000000000 + 7;
const int INF = 1000000000;
const int maxn = 2000 + 10;
int T,n,m;
ll x,y,x3,y3;
struct node {
ll x, y;
}a[maxn];
int main() {
scanf("%d%I64d%I64d%I64d%I64d",&n,&x,&y,&x3,&y3);
ll max1 = 0, max2 = 0;
for(int i=0;i<n;i++) {
scanf("%I64d%I64d",&a[i].x,&a[i].y);
ll v = (x - a[i].x)*(x - a[i].x) + (y - a[i].y)*(y - a[i].y);
max1 = max(max1, v);
v = (x3 - a[i].x)*(x3 - a[i].x) + (y3 - a[i].y)*(y3 - a[i].y);
max2 = max(max2, v);
}
ll ans = max2 + max1;
for(int i=0;i<=n;i++) {
ll v = (x - a[i].x)*(x - a[i].x) + (y - a[i].y)*(y - a[i].y);
if(i == n) v = 0;
ll hehe = 0;
for(int j=0;j<n;j++) {
ll cur = (x - a[j].x)*(x - a[j].x) + (y - a[j].y)*(y - a[j].y);
if(cur <= v) continue;
cur = (x3 - a[j].x)*(x3 - a[j].x) + (y3 - a[j].y)*(y3 - a[j].y);
hehe = max(hehe, cur);
}
ll u = v + hehe;
if(ans == -1) ans = u;
else ans = min(ans, u);
}
printf("%I64d\n",ans);
return 0;
}
D. Polyline
思路:不难想到, 最多三条折线就可以穿过任意3个点, 分情况讨论即可:
当三个点的x或者y坐标相同时输出1
当有两个点的x相同时, 如果第三个点的y坐标不介于另外两个点之间时,输出2; 同理当两个点y相同时......
其他情况输出3
细节参见代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int mod = 1000000000 + 7;
const int INF = 1000000000;
const int maxn = 100;
int T,n,m;
struct node {
ll x, y;
}a[10];
int main() {
for(int i=1;i<=3;i++) {
scanf("%I64d%I64d",&a[i].x,&a[i].y);
}
if((a[1].x == a[2].x && a[2].x == a[3].x)||(a[1].y == a[2].y &&a[2].y == a[3].y)) {
printf("1\n"); return 0;
}
else {
for(int i=1;i<=3;i++) {
for(int j=1;j<=3;j++) {
if(i == j) continue;
if(a[i].x == a[j].x) {
int k;
for(k=1;k<=3;k++) {
if(k != i && k != j) break;
}
ll l = min(a[i].y, a[j].y);
ll r = max(a[i].y, a[j].y);
if(a[k].y <= l || a[k].y >= r) { printf("2\n"); return 0; }
}
if(a[i].y == a[j].y) {
int k;
for(k=1;k<=3;k++) {
if(k != i && k != j) break;
}
ll l = min(a[i].x, a[j].x);
ll r = max(a[i].x, a[j].x);
if(a[k].x <= l || a[k].x >= r) { printf("2\n"); return 0; }
}
}
}
printf("3\n");
}
return 0;
}
E. XOR and Favorite Number
思路:莫队算法,尽快学会,然后补上。