codeforces-1133 (div3)

A.先全部化成分钟数,取平均数之后化成正常时刻。

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 110;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
int main(){
    int h1,m1,h2,m2;
    scanf("%d:%d %d:%d",&h1,&m1,&h2,&m2);
    int num = (h2 - h1) * 60 + (m2 - m1);
    num /= 2; m1 += num;
    while(m1 >= 60){
        h1++;
        m1 -= 60;
    } 
    printf("%02d:%02d",h1,m1);
    return 0;
}
A

B.所有数全部对K取余之后就能知道可以匹配他的兄弟是谁了,计数直接算即可。

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 2e5 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
int a[maxn];
int num[maxn];
int main(){
    Sca2(N,K);
    for(int i = 1; i <= N ; i ++){
        scanf("%d",&a[i]);
        a[i] %= K;
        num[a[i]]++;
    }
    int ans = num[0] / 2;
    for(int i = 1; i + i <= K; i ++){
        if(i + i == K) ans += num[i] / 2;
        else ans += min(num[i],num[K - i]);
    }
    Pri(ans * 2);
    return 0;
}
B

C.一个类似简化版的尺取即可。

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 2e5 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
int a[maxn];
int main(){
    Sca(N);
    for(int i = 1; i <= N ; i ++) Sca(a[i]);
    sort(a + 1,a + 1 + N);
    int s = 1,t = 1;
    int ans = 0;
    for(int i = 1; i <= N ; i ++){
        while(t < N && a[t + 1] - a[i] <= 5) t++;
        ans = max(ans,t - i + 1);
    }
    Pri(ans);
    return 0;
}
C

D.由于使每个位置取0的D有一个固定的数,map统计一下相同D的最大个数即可。

这里选择用结构体重载一下运算符处理,double 和 long double 都WA了,所以化成了分数最简比。

要注意如果要用map去重,不但要重载 == ,还有 <,最好可以每一个元素都在 < 里面讨论到,使得map排序结果可以确定

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const long double eps = 1e-12;
const int maxn = 2e5 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
LL a[maxn],b[maxn];
struct Node{
    LL x,y;
    Node(){}
    Node(LL x,LL y):x(x),y(y){}
    friend bool operator == (Node a,Node b){
        return a.x == b.x && a.y == b.y;
    }
    friend bool operator < (Node a,Node b){
        if(a.x == b.x) return a.y < b.y;
        return a.x < b.x;
    }
};
LL gcd(LL a,LL b){
    return !b?a:gcd(b,a % b);
}
map<Node,int>P;
int main(){
    Sca(N);
    for(int i = 1; i <= N ; i ++) scanf("%lld",&a[i]);
    for(int i = 1; i <= N ; i ++) scanf("%lld",&b[i]);
    int ans = 0,flag = 0;
    for(int i = 1;i <= N ; i ++){
        if(!a[i]){
            if(!b[i]) flag++;
            continue;
        }
        Node d;
        if(!b[i]){
            d = Node(0,0);
        }else{
            LL g = gcd(abs(a[i]),abs(b[i]));
            int flag = 1;
            if(a[i] < 0) flag *= -1;
            if(b[i] < 0) flag *= -1;
            d = Node(flag * abs(b[i]) / g,abs(a[i]) / g);
        }
        P[d]++;
        ans = max(ans,P[d]);
    }
    Pri(ans + flag);
    return 0;
}
D

E.C题的扩展,dp[i][j]记录有1 ~ j之间选i只队最多可以选多少人,直接递推即可。

5000 * 5000有很大MLE的风险,但是第一层i可以直接省略掉,空间复杂度为O(n)

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 5010;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
int a[maxn];
int pre[maxn];
int dp[maxn];
int main(){
    Sca2(N,K);
    for(int i = 1; i <= N ; i ++) Sca(a[i]);
    sort(a + 1,a + 1 + N);
    int t = 0;
    for(int i = 1; i <= N; i ++){
        while(t <= N && a[t + 1] - a[i] <= 5){
            t++; pre[t] = i;
        }
    }
    for(int i = 1; i <= K ; i ++){
        for(int j = N; j >= 1; j --){
            dp[j] = max(dp[j],dp[pre[j] - 1] + j - pre[j] + 1);
        }
        for(int j = 1; j <= N ; j ++) dp[j] = max(dp[j],dp[j - 1]);
    }
    Pri(dp[N]);
    return 0;
}
E

F1.取ind最多的点,将所有和他相邻的点率先加入树边,然后并查集处理加入余下的树边

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 2e5 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
int ind[maxn];
int fa[maxn];
void init(){
    for(int i = 0 ; i <= N ; i ++) fa[i] = i;
}
int find(int t){
    if(t == fa[t]) return t;
    return fa[t] = find(fa[t]);
}
int Union(int a,int b){
    a = find(a); b = find(b);
    if(a == b) return 0;
    fa[a] = b;
    return 1;
}
PII E[maxn];
int main(){
    Sca2(N,M); init();
    for(int i = 1; i <= M ; i ++){
        int u,v; Sca2(u,v);
        E[i].fi = u; E[i].se = v;
        ind[u]++; ind[v]++;
    }
    int Max = 1;
    for(int i = 1; i <= N ; i ++){
        if(ind[Max] < ind[i]) Max = i;
    }
    int ans = 0;
    for(int i = 1; i <= M ; i ++){
        if(E[i].fi == Max || E[i].se == Max){
            if(Union(E[i].fi,E[i].se)){
                ans++;
                printf("%d %d
",E[i].fi,E[i].se);
            }
        }
    }
    for(int i = 1; i <= M && ans < N - 1; i ++){
        if(Union(E[i].fi,E[i].se)){
            ans++;
            printf("%d %d
",E[i].fi,E[i].se);
        }
    }
    return 0;
}
F1

F2.一开始以为点1出去的桥必须联通,其他任意,后来发现并不。

删除所有1相邻的边之后产生的连通分量,1需要有边和每一个连通分量有边,其余剩下的位置才是任意。

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);  
#define Pri(x) printf("%d
", x)
#define Prl(x) printf("%lld
",x);  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 2e5 + 10;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
struct Edge{
    int to,next;
    bool cut;
}edge[maxn * 2];
int head[maxn],tot;
int fa[maxn];
int sum;
void init(){
    for(int i = 0 ; i <= N ; i ++) head[i] = -1;
    tot = 0;
}
int find(int x){
    if(x == fa[x]) return x;
    return fa[x] = find(fa[x]);
}
int Union(int a,int b){
    a = find(a); b = find(b);
    if(a == b) return 0;
    fa[a] = b; sum++;
    return 1;
}
void add(int u,int v){
    edge[tot].to = v;
    edge[tot].next = head[u];
    edge[tot].cut = 0;
    head[u] = tot++;
}
int ind[maxn];
vector<PII>ans;
int main(){
    Sca3(N,M,K); init();
    for(int i = 0 ; i <= N ; i ++) fa[i] = i;
    for(int i = 1; i <= M ; i ++){
        int u = read(),v = read();
        add(u,v); add(v,u);
        if(u != 1 && v != 1) Union(u,v);
        ind[u]++; ind[v]++;
    }
    for(int j = head[1]; ~j ; j = edge[j].next){
        if(Union(1,edge[j].to)){
            edge[j].cut = edge[j ^ 1].cut = 1;
        }
    }
    sum = 0;
    for(int i = 0; i <= N ; i ++) fa[i] = i;
    for(int i = head[1]; ~i; i = edge[i].next){
        if(edge[i].cut && Union(1,edge[i].to)){
            ans.pb(mp(1,edge[i].to));
            K--;
        }
    }
    for(int i = 1; i <= N; i ++){
        for(int j = head[i]; ~j; j = edge[j].next){
            if((i == 1 || edge[j].to == 1) && K <= 0) continue;
            if(Union(edge[j].to,i)){
                if(i == 1 || edge[j].to == 1) K--;
                ans.pb(mp(i,edge[j].to));
            }
        }
    }
    if(sum < N - 1 || K){
        puts("NO");
        if(M == 160698){
            cout << sum << " " << K << endl;
        }
        return 0;
    }
    puts("YES");
    for(int i = 0 ; i < ans.size(); i ++){
        printf("%d %d
",ans[i].fi,ans[i].se);
    }
    return 0;
}
F2
原文地址:https://www.cnblogs.com/Hugh-Locke/p/10704798.html