题目链接:点击打开链接
这次的比赛比较简单, 有些坑点, 主要是考思维的严密性。。。
比赛时做出了前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; }
注意全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; }
思路: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; }
思路:不难想到, 最多三条折线就可以穿过任意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; }
思路:莫队算法,尽快学会,然后补上。