2020牛客暑期多校训练营(第二场)

B.Boundary

  • 题意就是给你n个点,要求原点在圆的边界上,问在圆上的点的最多的圆,输出边界上有题中所给点的最大个数。
    我一开始读错题意了。以为是以原点为圆心。。然后直接遍历每个点和其他点的距离就是半径个数取最大,样例也过了。。
    但是后来发现原点是在边界上的。。这道题其实就可以利用三点构成一个圆,我们将每两个点组合然后再包括原点,求出圆心,
    求出所有的圆心用map存入,那么他的最大的size()+1就是他的圆上最大的点数,因为一个圆心他有1次的时候,
    这时候在上面是有2个点的,因为原点和那两个点组成的圆心,但是原点不算,因此此时有两个点,当圆心出现了两次,
    那么说明比之前又多了一个另外的点,这时候就会有两次圆心,
    前提是遍历点的时候是i(1,n),j(i+1,n),这样就避免了重复的情况。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <map>
#include <string>
#include <stack>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
#include<limits.h>
#define S(X) scanf("%d",&(X))
#define SS(X, Y) scanf("%d%d",&(X),&(Y))
#define SSS(X,Y,Z) scanf("%d%d%d",&(X),&(Y),&(Z))
#define SL(X) scanf("%lld",&(X))
#define SLL(X, Y) scanf("%lld%lld",&(X),&(Y))
using namespace std;
typedef double db;
typedef long long ll;
const int mod = 998244353;
const double eps = 1e-6;
const int maxn = 4e3 + 7;
struct Point
{ //点
    double x,y;
    Point(){}
    Point(double _x,double _y)
    {
        x = _x; y = _y;
    }
    Point operator +(const Point &b)const
    {
        return Point(x + b.x, y + b.y);
    }
    Point operator -(const Point &b)const
    {
        return Point(x - b.x, y - b.y);
    }
    bool friend operator<(const Point& p1,const Point& p2){
        if(fabs(p1.x-p2.x)>eps)return p1.x<p2.x;return p1.y<p2.y;
    }
    double operator *(const Point &b)const
    { //点积
        return x*b.x + y*b.y;
    }
    double friend operator^(const Point& p1,const Point& p2){
        return p1.x*p2.y-p2.x*p1.y;
    }
}p[maxn];
map<Point,int>mp;
Point xin(Point a, Point b, Point c)
{
    double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1 * a1 + b1 * b1) / 2.0;
    double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2 * a2 + b2 * b2) / 2.0;
    double d = a1 * b2 - a2 * b1;
    return Point(a.x + (c1 * b2 - c2 * b1) / d, a.y + (a1 * c2 - a2 * c1) / d);
}
int main(){
    int n;
    S(n);
    for(int i = 0;i < n;i++){
        scanf("%lf%lf",&p[i].x,&p[i].y);
    }
    if(n <= 2) {
        printf("%d\n",n);
        return 0;
        }
    int ans=0;
    for(int i = 0;i < n;i++){
        mp.clear();
        for(int j = i + 1;j < n;j++){
            if(abs(p[i] ^ p[j]) >= eps) {
            Point xinn= xin(Point(0,0),p[i],p[j]);
            mp[xinn]++;
            ans = max(ans,mp[xinn]);
           }
        }
    }
    printf("%d\n", ans + 1);
    return 0;
}

C.Cover the Tree

  • 很容易发现就是找叶子结点就可以了,然后将他们输出即可,数据有点假感觉。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <map>
#include <string>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
#define S(X) scanf("%d",&(X))
#define SS(X, Y) scanf("%d%d",&(X),&(Y))
#define SSS(X,Y,Z) scanf("%d%d%d",&(X),&(Y),&(Z))
#define SL(X) scanf("%lld",&(X))
#define SLL(X, Y) scanf("%lld%lld",&(X),&(Y))
using namespace std;
typedef double db;
typedef long long ll;
const int mod = 998244353;
const int maxn=5e5+100;
int main()
{
	#ifdef ONLINE_JUDGE
    #else
        freopen(".vscode/in.txt","r",stdin);
    #endif
    vector<int>v;
    int n;
    S(n);
    int a[maxn];
    int x,y;
    for(int i=0;i<n-1;i++)
    {
        SS(x,y);
        a[x]++;a[y]++;
    }
    for(int i=1;i<=n;i++)
    {
        if(a[i]==1)
            v.push_back(i);
    }
    printf("%d\n",(v.size()+1)/2);
    for(int i=0;i<(v.size()+1)/2;i++)
    {
        printf("%d %d\n",v[i],v[i+v.size()/2]);
    }
	return 0;
}

D.Duration

  • 完全签到题。给你时间求出秒数,一小时3600秒,一分钟60秒,做差即可。
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<string.h>
#include<cstring>
#include<set>
#include<queue>
#include<algorithm>
#include<math.h>
#include<stdio.h>
#include<map>
#include<stack>
#include<list>
#define pii pair<int, int>
#define pll pair<LL, LL>
#define pil pair<int, LL>
#define pli pair<LL, int>
#define mp make_pair
#define pb push_back
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define MINF 0x3f3f3f3f
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const LL LLINF = 1e18;
const int INF = 1e9;
const int MOD = 20101009;
const int HMOD = 999959;
const int VMOD = 5000000;
const int MAXN = 3e5+10;
const int MAXM = 5e5+10;
const int INV = 10050505;
const LL LLINV = 1e18;
const double eps = 1e-3;
int dirx[5] = {0, -1, 1, 0, 0}, diry[5] = {0, 0, 0, -1, 1};
 
int h1, m1, s1, h2, m2, s2;
 
int main()
{
IOS;
    scanf("%d:%d:%d", &h1, &m1, &s1);
    scanf("%d:%d:%d", &h2, &m2, &s2);
    int l = h1*3600+m1*60+s1, r = h2*3600+m2*60+s2;
    printf("%d\n", abs(r-l));
 
    return 0;
}

F.Fake Maxpooling

  • 这题没用单调队列维护,用dp直接过了,题目要求你算出所有k*k的子矩阵里面最大的元素之和,那么你把每个元素当前的值变成左边和上面的元素的最大值,那么矩阵lcm[k][k]这个位置就是第一个子矩阵的最大值,同理之后每一个元素都是一个子矩阵的最大值,我们只要将[k][k]~[n][m]这里面的元素累加即可。蛮假的。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <map>
#include <string>
#include <stack>
#include <cmath>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
#define S(X) scanf("%d",&(X))
#define SS(X, Y) scanf("%d%d",&(X),&(Y))
#define SSS(X,Y,Z) scanf("%d%d%d",&(X),&(Y),&(Z))
#define SL(X) scanf("%lld",&(X))
#define SLL(X, Y) scanf("%lld%lld",&(X),&(Y))
using namespace std;
typedef double db;
typedef long long ll;
const int mod = 998244353;
const int maxn=2e5+100;
int main()
{
	#ifdef ONLINE_JUDGE
    #else
        freopen(".vscode/in.txt","r",stdin);
    #endif
    int lcm[5005][5005]={0};
    int n,m,k;
    SSS(n,m,k);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            lcm[i][j]=(i*j)/(__gcd(i,j));
    // for(int i=1;i<=n;i++)
    // {
    //     for(int j=1;j<=m;j++)
    //     {
    //         cout<<lcm[i][j]<<" ";
    //     }
    //     cout<<endl;
    // }
    if(k!=1){
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
                lcm[i][j]=max(lcm[i][j],max(lcm[i-1][j],lcm[i][j-1]));
    }
    ll ans=0;
    for(int i=k;i<=n;i++)
        for(int j=k;j<=m;j++)
                ans+=lcm[i][j];
    printf("%lld\n",ans);
	return 0;
}
posted @ 2020-07-16 11:36  branna  阅读(175)  评论(0编辑  收藏  举报