2013多校训练赛第四场 总结
HDU 4632~4642
先贴一下通过的代码,总结迟点再说~
4637 Rain on your Fat brother(我唯一出的一题,明明很水,可是就是好少人过- -)
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 7 using namespace std; 8 9 const double EPS = 1e-8; 10 const double PI = acos(-1.0); 11 inline int sgn(double x) { return (x > EPS) - (x < -EPS);} 12 13 struct Point { 14 double x, y; 15 bool mk; 16 Point() {} 17 Point(double x, double y) : x(x), y(y) {} 18 bool operator < (Point a) const { return sgn(x - a.x) < 0 || sgn(x - a.x) == 0 && y < a.y;} 19 bool operator == (Point a) const { return sgn(x - a.x) == 0 && sgn(y - a.y) == 0;} 20 Point operator + (Point a) { return Point(x + a.x, y + a.y);} 21 Point operator - (Point a) { return Point(x - a.x, y - a.y);} 22 Point operator * (double p) { return Point(x * p, y * p);} 23 Point operator / (double p) { return Point(x / p, y / p);} 24 } ; 25 26 inline double cross(Point a, Point b) { return a.x * b.y - a.y * b.x;} 27 inline double dot(Point a, Point b) { return a.x * b.x + a.y * b.y;} 28 inline double veclen(Point a) { return sqrt(dot(a, a));} 29 inline Point vecunit(Point a) { return a / veclen(a);} 30 inline Point normal(Point a) { return Point(-a.y, a.x) / veclen(a);} 31 template<class T> T sqr(T x) { return x * x;} 32 33 struct Line { 34 Point s, t; 35 Line() {} 36 Line(Point s, Point t) : s(s), t(t) {} 37 Point vec() { return t - s;} 38 Point point(double x) { return s + vec() * x;} 39 } ; 40 inline Point llint(Line a, Line b) { return a.point(cross(b.vec(), a.s - b.s) / cross(a.vec(), b.vec()));} 41 inline bool onseg(Point x, Point a, Point b) { return sgn(cross(a - x, b - x)) == 0 && sgn(dot(a - x, b - x)) <= 0;} 42 43 struct Circle { 44 Point c; 45 double r; 46 Circle() {} 47 Circle(Point c, double r) : c(c), r(r) {} 48 bool in(Point a) { return sgn(veclen(a - c) - r) < 0;} 49 } ; 50 51 int clint(Circle c, Line l, Point *sol) { 52 Point nor = normal(l.vec()), ip = llint(l, Line(c.c, c.c + nor)); 53 if (!c.in(ip)) return 0; 54 Point dxy = vecunit(l.vec()) * sqrt(sqr(c.r) - sqr(veclen(ip - c.c))); 55 sol[0] = ip + dxy, sol[1] = ip - dxy; 56 return 2; 57 } 58 59 int lpint(Line l, Point a, Point b, Point c, Point *sol) { 60 int ret = 0; 61 if (sgn(cross(l.vec(), a - b)) != 0) { 62 sol[ret] = llint(l, Line(a, b)); 63 if (onseg(sol[ret], a, b)) ret++; 64 } 65 if (sgn(cross(l.vec(), c - b)) != 0) { 66 sol[ret] = llint(l, Line(c, b)); 67 if (onseg(sol[ret], c, b)) ret++; 68 } 69 if (sgn(cross(l.vec(), a - c)) != 0) { 70 sol[ret] = llint(l, Line(a, c)); 71 if (onseg(sol[ret], a, c)) ret++; 72 } 73 if (ret < 2) return 0; 74 sort(sol, sol + ret); 75 if (ret == 3) { 76 if (sol[0] == sol[1]) sol[1] = sol[2]; 77 } 78 if (sol[0] == sol[1]) return 0; 79 return 2; 80 } 81 82 Point ips[11111]; 83 84 int main() { 85 //freopen("in", "r", stdin); 86 int T, n; 87 double v1, v2, v, t, x; 88 double r, h; 89 Point O, ip[5]; 90 scanf("%d", &T); 91 for (int cas = 1; cas <= T; cas++) { 92 scanf("%lf%lf%lf%lf%lf", &v1, &v2, &v, &t, &x); 93 double tm = v2 * t / (v2 - v1); 94 Line l = Line(Point(x, 0), Point(x - v1 * tm, v * tm)); 95 scanf("%d", &n); 96 int tt = 0; 97 for (int i = 0; i < n; i++) { 98 scanf("%lf%lf%lf%lf", &O.x, &O.y, &r, &h); 99 int ipp = lpint(l, Point(O.x + r, O.y), Point(O.x - r, O.y), Point(O.x, O.y + h), ip); 100 if (ipp) { 101 if (ip[1] < ip[0]) swap(ip[0], ip[1]); 102 for (int i = 0; i < 2; i++) ip[i].mk = i & 1, ips[tt++] = ip[i]; 103 } 104 int ipc = clint(Circle(O, r), l, ip); 105 if (ipc) { 106 if (ip[1] < ip[0]) swap(ip[0], ip[1]); 107 if (sgn(ip[1].y - O.y) >= 0) continue; 108 if (sgn(ip[0].y - O.y) > 0) ip[0] = llint(l, Line(O, O + Point(1.0, 0))); 109 if (ip[0] == ip[1]) continue; 110 for (int i = 0; i < 2; i++) ip[i].mk = i & 1, ips[tt++] = ip[i]; 111 } 112 } 113 sort(ips, ips + tt); 114 int cnt = 0; 115 double sum = 0, lp = x - v1 * tm, rp = x, ls = lp; 116 for (int i = 0; i < tt; i++) { 117 if (ips[i].x > rp) break; 118 if (ips[i].x < lp) { 119 if (ips[i].mk) cnt--; 120 else cnt++; 121 } else { 122 if (ips[i].mk) { 123 if (cnt == 1) sum += ips[i].x - ls; 124 cnt--; 125 } else { 126 if (cnt == 0) ls = ips[i].x; 127 cnt++; 128 } 129 } 130 } 131 if (cnt > 0) sum += rp - ls; 132 printf("Case %d: %.4f\n", cas, sum / v1); 133 } 134 return 0; 135 }
4642 Fliping game(队友xdp出的)
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 6 int main(){ 7 int t; 8 cin>>t; 9 while(t--){ 10 int n,m,k; 11 cin>>n>>m; 12 for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&k); 13 if(k) puts("Alice"); 14 else puts("Bob"); 15 } 16 return 0; 17 }
4632 Palindrome subsequence(队友ly出的)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 const int N = 1087; 5 const int mod = 10007; 6 7 char s[N]; 8 int dp[N][N]; 9 10 int main(){ 11 int t,cas=1; 12 scanf("%d",&t); 13 while(t--){ 14 scanf("%s",s); 15 int n=strlen(s); 16 for(int i=0;i<n;i++){ 17 dp[i][i]=1; 18 } 19 for(int len=2;len<=n;len++){ 20 for(int i=0;i+len<=n;i++){ 21 int j=i+len-1; 22 dp[i][j]=(dp[i+1][j]+dp[i][j-1])%mod; 23 if(s[i]!=s[j]&&i+1<=j-1) dp[i][j]=(dp[i][j]-dp[i+1][j-1]+mod)%mod; 24 if(s[i]==s[j]) dp[i][j]=(dp[i][j]+1)%mod; 25 } 26 } 27 printf("Case %d: %d\n",cas++,dp[0][n-1]); 28 } 29 return 0; 30 }
4639 Hehe(队友ly出的)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 const int N = 10087; 5 const int mod = 10007; 6 7 char s[200000]; 8 int f[N]; 9 10 void init(){ 11 f[0]=1,f[1]=1,f[2]=2; 12 for(int i=3;i<N;i++){ 13 f[i]=(f[i-1]+f[i-2])%mod; 14 } 15 } 16 17 int main(){ 18 init(); 19 int t,cas=1; 20 scanf("%d",&t); 21 while(t--){ 22 scanf("%s",s); 23 int res=1,len=strlen(s); 24 for(int i=0;i<len-1;){ 25 int n=0; 26 while(i<len&&s[i]=='h'&&s[i+1]=='e'){ 27 n++; 28 i+=2; 29 } 30 res=(res*f[n])%mod; 31 i++; 32 } 33 printf("Case %d: %d\n",cas++,res); 34 } 35 return 0; 36 }
4635 Strongly connected (队友ly差点就出了,结果比赛结束才写完调过)
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 #include<queue> 6 #include<vector> 7 #include<stack> 8 typedef long long LL; 9 10 11 const int N = 100005; 12 using namespace std; 13 int n,m; 14 struct edge{ 15 int u,v,next; 16 }e[N*10]; 17 int tot,pre[N]; 18 int out[N],in[N]; 19 int cnt[N]; 20 int dfn[N],low[N],id[N],st[N]; 21 int top,scc,num; 22 bool vis[N]; 23 24 void init(){ 25 tot=0; 26 memset(pre,-1,sizeof(pre)); 27 } 28 29 void add(int u,int v){ 30 edge E={u,v,pre[u]}; 31 e[tot]=E,pre[u]=tot++; 32 } 33 34 void input(){ 35 int u,v; 36 while(m--){ 37 scanf("%d%d",&u,&v); 38 add(u,v); 39 } 40 } 41 42 void dfs(int u,int fa){ 43 dfn[u]=low[u]=++num; 44 vis[u]=1,st[++top]=u; 45 for(int i=pre[u];i!=-1;i=e[i].next){ 46 int v=e[i].v; 47 if(!dfn[v]){ 48 dfs(v,u); 49 low[u]=min(low[u],low[v]); 50 } 51 else if(vis[v]) low[u]=min(low[u],dfn[v]); 52 } 53 if(low[u]==dfn[u]){ 54 ++scc; 55 cnt[scc]=0; 56 while(1){ 57 int v=st[top--]; 58 id[v]=scc,vis[v]=0; 59 cnt[scc]++; 60 if(v==u) break; 61 } 62 } 63 } 64 65 void tarjan(){ 66 memset(dfn,0,sizeof(dfn)); 67 memset(vis,0,sizeof(vis)); 68 scc=num=top=0; 69 for(int i=1;i<=n;i++){ 70 if(!dfn[i]) dfs(i,-1); 71 } 72 } 73 74 LL cal(){ 75 memset(out,0,sizeof(out)); 76 memset(in,0,sizeof(in)); 77 if(scc==1) return -1; 78 for(int i=0;i<tot;i++){ 79 int u=id[e[i].u],v=id[e[i].v]; 80 if(u==v) continue; 81 out[u]=1,in[v]=1; 82 } 83 LL sum=(LL)n*(n-1)-tot,res=-1; 84 for(int i=1;i<=scc;i++){ 85 if(!in[i]||!out[i]){ 86 if(res==-1||res<(LL)sum-cnt[i]*(n-cnt[i])) res=(LL)sum-cnt[i]*(n-cnt[i]); 87 } 88 } 89 return res; 90 } 91 92 93 94 int main(){ 95 int t,cas=1; 96 scanf("%d",&t); 97 while(t--){ 98 scanf("%d%d",&n,&m); 99 init(); 100 input(); 101 tarjan(); 102 printf("Case %d: %I64d\n",cas++,cal()); 103 } 104 return 0; 105 106 107 }
UPD:
补上总结。
这次的比赛开场还是挺顺利的。开始的时候我就发现06这道几何题,看到这题感觉不难,那时认为应该45min内大board会有队伍出这题的了。结果意想不到的是到最后结束才10支队伍出了这题。在两位队友出三题最多人通过的题的同时,我在第二个小时即将结束的时候写出了06的代码。测试sample通过,然后提交的时候wa了。开始的时候以为我的那个重合没判好,于是我就重新打了那部分,测了几组自己搞的数据,发现还是不行。于是我就只好先睡一下休息休息了。睡了半个钟起来,还是想不到怎么错,继续自己一个debug。他们两个就去搞03,03是一道搜索,但是被他们搞得好复杂。一直搞到封榜了,他们还在搞03,于是就拉一个队友ly来帮我debug,他一脸不愿意的样子,我跟他说我思路,说到一个关键点的时候,突然想起自己的一个逻辑错误,改过来马上通过。这时还只有4题的数量。如果他早点过来帮忙,或许早就过了。- -
他们继续搞03,我就看了一下07,想了20+min,无果。于是就看到04这道超多人过的题了。04是强联通分量,一道图论。队友ly居然看了题说不懂,然后就继续搞03,还叫我不要想04了,不会做的。搞到那时我犹豫了一下,到底想还是不想呢?- - 最后还是想了5min,这5min里,我先是将图画出来,然后就往缩点的方向想了一下,发现缩完点以后,不是强联通的部分点越少越好,于是就得到一个猜想,缩点以后的点全部都不连与外界交流的边不就可以了?然后其他的边全都连上!(其实还有外面的点不练进来的这种情况,可惜当时我没想到)。我逐渐证实了我的想法的正确性,然后搞出一个公式来。最后15min左右,ly才想懂了我说,结果他用了10min敲强联通,最后因为太赶了,没来得及debug就交了,wa了两次。结束以后2min左右就被他改对,提交通过。
于是这次就抱着03和04两个遗憾结束了比赛。赛后回去,xdp居然说02就是一个裸的Polya,其实他能做。那时我对两位队友就如同心中有千万只草泥马飞奔而过的愤怒了!其实我还真想说,我比赛中间就多次提出要放弃03,结果两个没一个接受,我也不好意思强求,最终就这样遗憾结束了。07我还花了不少时间才看懂怎么做,居然比赛的时候跟我说这是数据结构,所以要我做。- - 反正这次就是各种策略错误,但愿以后不会再发生这样的情况。
——written by Lyon