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
", cas, sum / v1);
133     }
134     return 0;
135 }
View Code

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 }
View Code

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
",cas++,dp[0][n-1]);
28     }
29     return 0;
30 }
View Code

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
",cas++,res);
34     }
35     return 0;
36 }
View Code

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
",cas++,cal());
103     }
104     return 0;
105 
106 
107 }
View Code

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

原文地址:https://www.cnblogs.com/LyonLys/p/2013_08_01_Lyon.html