Codeforces Round #378 (Div. 2) Analyses
懒癌晚期,没的救了xD
Problems:一只蚂蚱从左跳到右,每次只能跳{A,E,I,O,U,Y},问两次跳之间的距离的最大值
Analysis:简单模拟即可
Tags:Implementation
B.Parade
Problems:给你n排士兵及每排士兵的左、右脚分别伸出的数目,可以交换其中一排的左右脚伸出数,问max{|L-R|}
Analysis:鉴于只有10^5,那么暴力交换就可以了
Tags:Implementation
Problems:给你一个序列和另一个序列,对于后者可以进行merge操作,条件为merge的前者大于后者(R)或后者大于前者(L),问是否可以使后者变成前者,并输出方案
Analysis:首先我们知道后面那个序列要是可能变成前者,那么最后构造出来的数肯定是一一对应的,所以可以从前向后构造,如果不能,则输出否即可,那么考虑构造,对于当前目的序列的x,在原序列若找到一段序列和为x,即视为构造成功,之后方案构造只需向右merge后向左merge再向右merge即可,具体可以看代码实现
Tags:Implementation, Two pointers
#include<cstdio> #include<cstring> #include<algorithm> //#include<iostream> #include<cmath> #include<queue> #include<map> #include<string> #include<vector> using namespace std; #define INF 2000000000 #define Clear(x, Num) memset(x, Num, sizeof(x)) #define Dig(x) ((x>='0') && (x<='9')) #define Neg(x) (x=='-') #define G_c() getchar() #define Maxn 1010 #define Maxe 100010 typedef long long ll; struct Data { int m; char s; }Ans[Maxe]; int n, a[Maxn], b[Maxn], k, Cnt; inline int gcd(int x, int y) { if (!y) return x; return gcd(y, x%y); } inline void read(int &x){ char ch; int N=1; while ((ch=G_c()) && (!Dig(ch)) && (!Neg(ch))); if (Neg(ch)) { N=-1; while ((ch=G_c()) && (!Dig(ch))); } x=ch-48; while ((ch=G_c()) && (Dig(ch))) x=x*10+ch-48; x*=N; } //inline void Insert(int u, int v) { To[Cnt]=v; Next[Cnt]=Head[u]; Head[u]=Cnt++; } inline void Go_die() { puts("NO"); exit(0); } int main() { read(n); for (int i=1; i<=n; i++) read(a[i]); read(k); for (int i=1; i<=k; i++) read(b[i]); int id=1, last=1; for (int i=1; i<=k; i++) { int Max=0, pos=0, _pos=0, Sig=0; for (; (id<=n) && (Sig<b[i]); id++) { Sig+=a[id]; if (Sig>b[i]) Go_die(); if (a[id]>Max) Max=a[id], pos=id; } if (Sig!=b[i]) Go_die(); if ((pos==last) && (a[pos+1]==Max)) while (a[pos+1]==Max) pos++; _pos=pos+1; int Res=i+pos-last; while ((_pos<id) && (a[_pos]<Max)) { Max+=a[_pos++]; Ans[++Cnt].m=Res; Ans[Cnt].s='R'; } int __pos=pos-1; while ((__pos>=last) && (a[__pos]<Max)) { Max+=a[__pos--]; Ans[++Cnt].m=Res--; Ans[Cnt].s='L'; } while ((_pos<id) && (a[_pos]<Max)) { Max+=a[_pos++]; Ans[++Cnt].m=Res; Ans[Cnt].s='R'; } if (Max!=b[i]) Go_die(); last=id; } if (last!=n+1) Go_die(); puts("YES"); for (int i=1; i<=Cnt; i++) printf("%d %c\n", Ans[i].m, Ans[i].s); }
Problems:给你n个长方形,最多选取两个长方形,问能切割出来的最大的球半径的方案
Analysis:这题反倒是比C题好写了,首先对于每个长方形,我们将边长排序,最大半径显然等于最短边的边长,之后考虑合并,合并肯定是有一个面一样然后让另一条边增长为优,所以只需维护面就可以了,需要用到map(或者离散化???)
Tags:Greedy, Data Structure
#include<cstdio> #include<cstring> #include<algorithm> //#include<iostream> #include<cmath> #include<queue> #include<map> #include<string> #include<vector> using namespace std; #define INF 2000000000 #define Clear(x, Num) memset(x, Num, sizeof(x)) #define Dig(x) ((x>='0') && (x<='9')) #define Neg(x) (x=='-') #define G_c() getchar() typedef long long ll; map<pair<int, int> , pair<int, int > > Srh; int n, a, b, c, Min, Mid, Max, Line_max, Merge, Id; inline int gcd(int x, int y) { if (!y) return x; return gcd(y, x%y); } inline void read(int &x){ char ch; int N=1; while ((ch=G_c()) && (!Dig(ch)) && (!Neg(ch))); if (Neg(ch)) { N=-1; while ((ch=G_c()) && (!Dig(ch))); } x=ch-48; while ((ch=G_c()) && (Dig(ch))) x=x*10+ch-48; x*=N; } //inline void Insert(int u, int v) { To[Cnt]=v; Next[Cnt]=Head[u]; Head[u]=Cnt++; } int main() { read(n); for (int i=1; i<=n; i++) { read(a), read(b), read(c); Max=max({a, b, c}), Min=min({a, b, c}), Mid=a+b+c-Max-Min; if (Min>Line_max) Line_max=Min, Id=i, Merge=-1; if (Srh[{Mid, Max}].first) { Min=min({Mid, Max, Min+Srh[{Mid, Max}].first}); if (Min>Line_max) { Line_max=Min; Id=i; Merge=Srh[{Mid, Max}].second; } } Min=min({a, b, c}); Srh[{Min, Mid}]=max(Srh[{Min, Mid}], {Max, i}); Srh[{Min, Max}]=max(Srh[{Min, Max}], {Mid, i}); Srh[{Mid, Max}]=max(Srh[{Mid, Max}], {Min, i}); } if (Merge==-1) { puts("1"); printf("%d\n", Id); } else { puts("2"); printf("%d %d\n", Id, Merge); } }