2020牛客多校训练第二场(待更新)

题目 完成情况
A. All with Pairs
B. Boundary
C.Cover the Tree
D. Duration
E.Exclusive OR
F.Fake Maxpooling
G.Greater and Greater
H.Happy Triangle
I.Interval
J.Just Shuffle
K.Keyboard Free

B.Boundary

题意:

给你n个点,任意两个点可以跟圆心确定一个圆(心),问这个圆最多包含n个点中的多少个?

分析:

n 2 ^2 2复杂度遍历点,可以保存圆心的坐标,将坐标和int做一个map映射,这里用pair会wa,可以自定义一个结构体,重载<,注意对于每次枚举的两个点和圆心,判断是否三点共线。

代码:

#include 
using namespace std;
typedef long long ll;
//typedef __int128 lll;
#define print(i) cout << "debug: " << i << endl
#define close() ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define mem(a, b) memset(a, b, sizeof(a))
const ll mod = 1e9 + 7;
const int maxn = 2e6;
const int inf = 0x3f3f3f3f;
struct Point
{
    double x, y;
    bool operator < (const Point b) const
    {
        return x != b.x ? x < b.x : y < b.y;
    }
}a[maxn];
int ans;
map<Point, int> m;
void solve(Point a,Point b,Point c)//三点共圆圆心公式
{
    double x=( (a.x*a.x-b.x*b.x+a.y*a.y-b.y*b.y)*(a.y-c.y)-(a.x*a.x-c.x*c.x+a.y*a.y-c.y*c.y)*(a.y-b.y) ) / (2.0*(a.y-c.y)*(a.x-b.x)-2*(a.y-b.y)*(a.x-c.x));
    double y=( (a.x*a.x-b.x*b.x+a.y*a.y-b.y*b.y)*(a.x-c.x)-(a.x*a.x-c.x*c.x+a.y*a.y-c.y*c.y)*(a.x-b.x) ) / (2.0*(a.y-b.y)*(a.x-c.x)-2*(a.y-c.y)*(a.x-b.x));
    m[{x,y}]++;
    ans=max(ans,m[{x,y}]);
}


int main()
{
    close();
    int n; cin >> n;
    for(int i = 1; i <= n; i++) cin >> a[i].x >> a[i].y;
    for(int i = 1; i <= n; i++)
    {
        m.clear();
        for(int j = i + 1; j <= n; j++)
        {
            if(a[i].x * a[j].y - a[i].y * a[j].x == 0) continue;
            solve(Point{0, 0}, a[i], a[j]);
        }
    }
    cout << ans + 1 << endl;
}

F.Fake Maxpooling

题意:

求最大池化的和

分析:

求出每一行中,[j, j + k - 1]的最大值,用一个单调队列做,并保存下来。然后对于每一列,对于保存下来的值,求[i, i +k- 1]求最大值,也是用单调队列实现,最后sum每次加队首元素的值就可。

代码:

#include 
using namespace std;
typedef long long ll;
//typedef __int128 lll;
#define print(i) cout << "debug: " << i << endl
#define close() ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define mem(a, b) memset(a, b, sizeof(a))
const ll mod = 1e9 + 7;
const int maxn = 5010;
const int inf = 0x3f3f3f3f;
int n, m, k;
int linemax[maxn][maxn];

int main()
{
    cin >> n >> m >> k;
    for(int i = 1; i <= n; i++)
    {
        deque<pair<int, int> > q;
        for(int j = 1; j <= m; j++)
        {
            ll lcmm = i * j / __gcd(i, j);
            while(!q.empty() && lcmm > q.back().second) q.pop_back();
            q.push_back(make_pair(j, lcmm));
            while(!q.empty() && j - q.front().first + 1 > k) q.pop_front();
            linemax[i][j] = q.front().second;
        }
    }
    ll sum = 0;
    for(int j = k; j <= m; j++)
    {
        deque<pair<int, int> > q;
        for(int i = 1; i <= n; i++)
        {
            while(!q.empty() && linemax[i][j] > q.back().second) q.pop_back();
            q.push_back(make_pair(i, linemax[i][j]));
            while(!q.empty() && i - q.front().first + 1 > k) q.pop_front();
            if(i >= k) sum += q.front().second;
        }
    }
    cout << sum << endl;
}

你可能感兴趣的:(牛客多校)