atcoder 076

日本人的比赛

C:如果两个数差了大于1无解,否则分类讨论

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010, mod = 1000000007;
int n, m;
ll a[N];
ll power(ll x, ll t)
{
    ll ret = 1;
    for(; t; t >>= 1, x = x * x % mod)
        if(t & 1)
            ret = ret * x % mod;
    return ret;
}
int main()
{
    scanf("%d%d", &n, &m);
    if(n < m) swap(n, m);
    if(n - m != 1 && n - m != 0)
    {
        puts("0");
        return 0;
    }
    a[0] = 1;
    for(int i = 1; i <= n + 1; ++i)
        a[i] = a[i - 1] * (ll)i % mod;
    if(n == m)
        printf("%lld\n", 2ll * a[n] % mod * a[m] % mod);
    else
        printf("%lld\n", a[n] % mod * a[m] % mod);
    return 0;
}

D:分别按xy排序,然后分别把相邻的差放进去做最小生成树。因为如果三个点xaxbxc,xa<xb<xc,那么连xa->xb->xc肯定比xa->xc优,也就是说连相邻的肯定最优。因为这n-1条边能构成最小生成树,而且是自己维度最优的,所以只要和最小的y比较就行了,肯定会有解,而且是最优的,因为我们不可能会去用其他的边。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 100010;
struct edge {
    int u, v;
    ll w;
    edge(int u, int v, ll w) : u (u), v (v), w (w) {}
};
struct data {
    ll x, y;
    int id;
} a[N];
int n;
int fa[N];
ll ans;
vector<edge> e;
bool cp(edge x, edge y)
{
    return x.w < y.w;
}
bool cp1(data x, data y)
{
    return x.x < y.x;
}
bool cp2(data x, data y)
{
    return x.y < y.y;
}
int find(int x)
{
    return x == fa[x] ? x : fa[x] = find(fa[x]);
}
int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i) fa[i] = i;
    for(int i = 1; i <= n; ++i)
    {
        scanf("%lld%lld", &a[i].x, &a[i].y);
        a[i].id = i;
    }
    sort(a + 1, a + n + 1, cp1);
    for(int i = 2; i <= n; ++i)
        e.push_back(edge(a[i].id, a[i - 1].id, a[i].x - a[i - 1].x));
    sort(a + 1, a + n + 1, cp2);
    for(int i = 2; i <= n; ++i)
        e.push_back(edge(a[i].id, a[i - 1].id, a[i].y - a[i - 1].y));
    sort(e.begin(), e.end(), cp);
    for(int i = 0; i < e.size(); ++i)
    {
        if(find(e[i].u) == find(e[i].v))
            continue;
        ans += e[i].w;
        fa[find(e[i].u)] = find(e[i].v);
    }
    printf("%lld\n", ans);
    return 0;
}

E:并没有AC,不知道哪里错了。

结论:不全在边框上的整数互相之间肯定能连起来。

只要考虑的是在边框上的点,防止出现ijij的情况,于是用一个栈从顺时针加入,如果加入的点和栈顶是同一种数字,那么弹出,否则加入,最后看栈是否为空。

wa

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
struct data {
    int x, y, id;
};
int n, r, c, top;
vector<data> v[4];
data st[N];
bool cp1(data x, data y)
{
    return x.x < y.x;
}
bool cp2(data x, data y)
{
    return x.x > y.x;
}
bool cp3(data x, data y)
{
    return x.y < y.y;
}
bool cp4(data x, data y)
{
    return x.y > y.y;
}
int main()
{
    scanf("%d%d%d", &r, &c, &n);
    for(int i = 1; i <= n; ++i)
    {
        data a, b; scanf("%d%d%d%d", &a.x, &a.y, &b.x, &b.y);
        a.id = b.id = i;
        if((a.x == 0 || a.x == c || a.y == 0 || a.y == r) && (b.x == 0 || b.x == c || b.y == 0 || b.y == r))
        {
            if(a.x == 0)
                v[0].push_back(a);
            else if(a.y == r)
                v[1].push_back(a);
            else if(a.x == c)
                v[2].push_back(a);
            else if(a.y == 0)
                v[3].push_back(a);
            if(b.x == 0)
                v[0].push_back(b);
            else if(b.y == r)
                v[1].push_back(b);
            else if(b.x == c)
                v[2].push_back(b);
            else if(b.y == 0)
                v[3].push_back(b);
        }
    }
    sort(v[0].begin(), v[0].end(), cp3);
    sort(v[1].begin(), v[1].end(), cp1);
    sort(v[2].begin(), v[2].end(), cp4);
    sort(v[3].begin(), v[3].end(), cp2);
    st[0].id = 0;
    for(int i = 0; i < 4; ++i)
        for(int j = 0; j < v[i].size(); ++j)
        {
            data x = v[i][j];
//            printf("x.id=%d x.x=%d x.y=%d\n", x.id, x.x, x.y);
            if(x.id == st[top].id)
                --top;
            else
                st[++top] = x;
        }
    puts(top == 0 ? "YES" : "NO");
    return 0;
}

时间: 2024-08-08 13:46:32

atcoder 076的相关文章

【题解】 AtCoder ARC 076 F - Exhausted? (霍尔定理+线段树)

题面 题目大意: 给你\(m\)张椅子,排成一行,告诉你\(n\)个人,每个人可以坐的座位为\([1,l]\bigcup[r,m]\),为了让所有人坐下,问至少还要加多少张椅子. Solution: 为什么加椅子?我们可以在最左边或最右边一直加直到人人都有座位. 首先这道题目抽象成二分图很简单,然后我们可以只要求解出人与座位的最大匹配是多少,总人数减去即可,但跑二分图最大匹配显然会超时,我们就可以往霍尔定理方面想. 然后你还需要知道一个霍尔定理推论:假设某个人的集合为\(X\),这个集合所对应的

Atcoder Regular Contest 076 F - Exhausted?题解

题目链接:F - Exhausted? 题目大意:有m个椅子在数轴上排列,第i张椅子(1≤i≤m)的坐标为i. 高桥君和他的朋友一共有n个人.高桥君他们因为玩了太久的游戏,大家的腰和背都很痛,所以他们很有必要坐在椅子上休息一下.高桥君他们每个人坐的椅子的坐标都很讲究,第i个人想坐在坐标在li以下(包括li)的椅子上,或者坐在坐标在ri以上(包括ri)的椅子上.当然,一个的椅子只能坐一个人. 可这样计算下去,可能会让他们不能都坐在椅子上休息.青木君关心高桥君他们的健康,尽可能多地增加椅子,让高桥君

AtCoder Regular Contest 075 E - Meaningful Mean 树状数组求顺序对, 前缀和

题目链接: http://arc075.contest.atcoder.jp/tasks/arc075_c 题意: 给你一个序列和一个数k,求有多少对l,r,使得a[l]+a[l+1]+...+a[r]的算术平均数大于等于k 1≤N≤2×10^5 1≤K≤10^9 1≤ai≤10^9 思路: 首先对于所有数减去k,这样就不用除(r-l+1), 然后我们发现所求的就是有多少对l,r,使得sum[r]-sum[l-1] >= 0, sum是减去k之后的序列的前缀和 用树状数组对sum求有多少个顺序对

LeetCode: Minimum Window Substring [076]

[题目] Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n). For example, S = "ADOBECODEBANC" T = "ABC" Minimum window is "BANC". Note: If there is no such

076 Minimum Window Substring

076 Minimum Window Substring 这道题就是用一个dictionary来跟踪有多少还需要Match的字母以及当前需要match的次数. 再用一个queue 来记录哪些字幕被Match了以及他们被match的顺序 from collections import defaultdict class Solution: # @param {string} s # @param {string} t # @return {string} def minWindow(self, s

AtCoder 2346 No Need

传送门:http://arc070.contest.atcoder.jp/tasks/arc070_b?lang=en 题意: 对于一个数组的任意一个子集,如果它的元素和大于等于K这个子集就叫做good subset,如果将一个数所在的所有good subset都减去这个数,这些集合依旧是good subset那么这个数被称为无用数.现在给定一个数组,求其中的无用数的个数.  题解: 如果一个数不是无用数,那么所有大于等于这个数的数都不会是无用数,那么我们先对这个数组进行排序,每次二分结果就行了

Atcoder Yet Another Palindrome Partitioning(状压dp)

Atcoder Yet Another Palindrome Partitioning 思路: 一个字符串满足条件的情况是奇数字母个数小于等于1,也就是异或起来是1<<j(0<=j<=25) 记mark是异或起来的值 状态转移: dp[mark]=dp[mark]+1; dp[mark]=min(dp[mark^(1<<j)]+1,dp[mark]);(0<=j<=25) 注意dp[0]被转移后可能会变成1,但是由它转移的需要dp[0]=0,所以每次记得把d

2018.03.04 晚上Atcoder比赛

C - March Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement There are N people. The name of the i-th person is Si. We would like to choose three people so that the following conditions are met: The name of every chosen per

Atcoder 091/092 C 2D Plane 2N Points[扫描线]

昨晚打了第一场atcoder...这题卡了1h...今天听课的时候听到了一个极相似的题... 题意:给出2n个点的坐标(x,y) 前n个是红点,剩下是蓝点,当一个红点的横纵坐标都小于一个蓝点的时候,他们可以匹配,求最大的匹配对数 按照横坐标排序,排序后从右往左扫描,发现蓝点将其纵坐标存入set中(因为已经按照横坐标排序,所以不需要考虑横坐标),发现红点从set中找一个能跟这个点匹配的最小的点(lower_bound),注意set::lower_bound是O(logn)的,std::lower_