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\n", x) #define Prl(x) printf("%lld\n",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; }
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\n", x) #define Prl(x) printf("%lld\n",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; }
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\n", x) #define Prl(x) printf("%lld\n",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; }
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\n", x) #define Prl(x) printf("%lld\n",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; }
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\n", x) #define Prl(x) printf("%lld\n",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; }
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\n", x) #define Prl(x) printf("%lld\n",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\n",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\n",E[i].fi,E[i].se); } } return 0; }
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\n", x) #define Prl(x) printf("%lld\n",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\n",ans[i].fi,ans[i].se); } return 0; }