【首先检讨,昨天晚上误解以为今天没有比赛,所以到实验室已经1个小时过去了,就lh大仙一个单刷,Orz】

【然后是来的路上惹怒了niuniu,我的错】

本场比赛是11年hnu出的多校训练,往往多校训练的题目质量都是比较好的,水题不会太多,考的知识面比较广和深或者很偏很难。

由于到实验室迟到了1个小时,lh大仙挂了B,H题和I都被秒了,于是我看了H,过了之后发现F题被dongfang队秒掉,我又转看F,由此陷入了深深的泥潭。Orz,膜拜F题1A!之后就去401一起做题了。

【H题】给定数N<=10^9,求a^2+b^2 = N的序对数,注意a,b可以正负。显然sqrt(N)暴力即可。59min, 1A。

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<string.h>
 4
 5 long long sq[1001000];
 6 int cnt;
 7 int judge(int m)
 8 {
 9     int l = 1, r = cnt;
10     while (l <= r)
11     {
12         int mid = (l + r)/2;
13         if (sq[mid] == m)
14         {
15             return true;
16         }
17         if (sq[mid] < m){
18             l = mid + 1;
19         }else{
20             r = mid - 1;
21         }
22     }
23     return false;
24 }
25 int calc(long long n)
26 {
27     if (n == 0)
28         return 1;
29     int res = 0;
30     for  (int i=1;i*i<=n;i++)
31     {
32         if (i*i == n)
33         {
34             res += 4;
35         }else{
36             if (judge(n - i * i))
37             {
38                 if (i*i == n - i*i)
39                     res += 4;
40                 else
41                     res += 4;
42             }
43         }
44     }
45
46     return res;
47 }
48 int main()
49 {
50     cnt = 0;
51     for (long long i=1;i*i<=1000000000;i++)
52     {
53         sq[++cnt] = i * i;
54     }
55     long long n;
56     while (scanf("%I64d",&n)==1)
57     {
58         printf("%d\n",calc(n));
59     }
60     return 0;
61 }

H(wangsouc)

【此时I题】已经被大仙秒掉,后面知道这个题是白书上的原题,他直接抄的代码。

I题,给定N个点,M条边的有向图,问至少加入多少条边,使得整个图为强连通的。scc+统计入度和出度为0的点,然后YY。模板题。61min,1A。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cmath>
  5 #include <string.h>
  6 #include <string>
  7 #include <vector>
  8 #include <stack>
  9
 10 using namespace std;
 11
 12 const int MAXN = 100000 + 10;
 13 vector<int> G[MAXN];
 14 int T, n, m;
 15 int pre[MAXN], lowlink[MAXN], sccno[MAXN], dfs_clock, scc_cnt;
 16 int in0[MAXN], out0[MAXN];
 17 stack <int> S;
 18
 19 void dfs(int u)
 20 {
 21     pre[u] = lowlink[u] = ++dfs_clock;
 22     S.push(u);
 23     for (int i = 0; i < G[u].size(); i++)
 24     {
 25         int v = G[u][i];
 26         if (!pre[v])
 27         {
 28             dfs(v);
 29             lowlink[u] = min(lowlink[u], lowlink[v]);
 30         }
 31         else if (!sccno[v])
 32         {
 33             lowlink[u] = min(lowlink[u], pre[v]);
 34         }
 35     }
 36
 37     if (lowlink[u] == pre[u])
 38     {
 39         scc_cnt++;
 40         for (;;)
 41         {
 42             int x = S.top(); S.pop();
 43             sccno[x] = scc_cnt;
 44             if (x == u) break;
 45         }
 46     }
 47 }
 48
 49 void find_scc(int n)
 50 {
 51     dfs_clock = scc_cnt = 0;
 52     memset(sccno, 0, sizeof(sccno));
 53     memset(pre, 0, sizeof(pre));
 54     for (int i = 0; i < n; i++)
 55     {
 56         if (!pre[i])dfs(i);
 57     }
 58 }
 59
 60 void input()
 61 {
 62     while (scanf("%d %d", &n, &m) != EOF)
 63     {
 64         for (int i = 0; i < n; i++)
 65         {
 66             G[i].clear();
 67         }
 68         for (int i = 0; i < m; i++)
 69         {
 70             int u, v;
 71             scanf("%d %d", &u, &v); u--; v--;
 72             G[u].push_back(v);
 73         }
 74
 75         find_scc(n);
 76
 77         for (int i = 1; i <= scc_cnt; i++) in0[i] = out0[i] = 1;
 78         for (int u = 0; u < n; u++)
 79         {
 80             for (int i = 0; i < G[u].size(); i++)
 81             {
 82                 int v = G[u][i];
 83                 if (sccno[u] != sccno[v]) in0[sccno[v]] = out0[sccno[u]] = 0;
 84             }
 85         }
 86
 87         int a = 0, b = 0;
 88         for (int i = 1; i <= scc_cnt; i++)
 89         {
 90             if (in0[i]) a++;
 91             if (out0[i]) b++;
 92         }
 93
 94         int ans = max(a, b);
 95         if (scc_cnt == 1) ans = 0;
 96         printf("%d\n", ans);
 97     }
 98 }
 99
100 int main()
101 {
102     input();
103     return 0;
104 }

I(lihe)

F题:给定N和1到N的一个排列,问序列中存不存在3个元素的等差子序列,Pi1 - Pi2 = Pi2 - Pi3,i1<i2<i3。N《=10000,时限4s。

我和niuniu讨论了下F题,尝试了一下暴力枚举N^2,g++提交TLE,然后发现有60组case之多。

我查看了一下dongfang队的记录,他们代码长度816 B(我们的743 B),内存使用384 KB,也就是差不多20000W的int型,运行了3187ms。

我认定了他们是暴力水过的。

Orz,niuniu给出了一种枚举的优化方式,枚举公差d,缩小范围,总复杂度控制在10^9内。我balabala写完提交,TLE。此时,我们又陷入了深深的泥潭。

lh大仙的B题,大意是,有N个cat和M个dog,有P个人,每个人喜欢某个cat(dog)和讨厌某个dog(cat),如果去掉了他不喜欢的动物保留了喜欢的,那么他就会开心。问,去掉一些动物最多能使得多少人开心。

这出现在白书上最大匹配的练习题目,没有给出解法。lh大仙就咬住一定是最大匹配。

这时,niuniu在继续做F,也在读别的题目,我想了想B,也读了读其他几个题目。

B题,我们始终以cat和dog为对象建立二分图求最大匹配,陷入了深深的泥潭,不得正解。144分钟的时候,dongfang队过了B题,我们分明听到了他们的讨论,确实是和匹配有关。

Orz,他们此时4题秒杀我们2题。

我看了board,B\E\F是此时过得最多的题目。

【听niuniu说了E题】,大意是,给定N个圆,求去掉最多多少个圆,使得第1、2、3个圆还能连通,3<=N<=200。

我推了推E,建图之后无法建立费用流模型,也找不出平面上圆相交的特殊性质。

后来灵光一闪,最终的路径,肯定是Y字形,也就是只用枚举A、B、C的第一个交点D,然后分别D到A\B\C的最短路。

写了个Floyd,提交TLE。case数比较多?转用了dijkstra,178min FB。

 1 #include<stdio.h>
 2 #include<math.h>
 3 #include<string.h>
 4 #include<algorithm>
 5
 6 int n;
 7 struct cir{
 8     int x, y, r;
 9 }sq[222];
10 int mp[222][222];
11 int calc(int p, int q)
12 {
13     return ((sq[p].x - sq[q].x) * (sq[p].x - sq[q].x) + (sq[p].y - sq[q].y) * (sq[p].y - sq[q].y) <= (sq[p].r + sq[q].r)*(sq[p].r + sq[q].r));
14 }
15 int dis[4][222];
16 int vis[222];
17 void spfa(int S, int * f)
18 {
19     memset(vis, 0, sizeof(vis));
20     for (int i=1;i<=n;i++)
21         f[i] = 100000;
22     f[S] = 1;
23     for (int i=1;i<=n;i++)
24     {
25         int p = 1;
26         int mm = 100000;
27         for (int j=1;j<=n;j++)
28             if (!vis[j] && f[j]<mm){
29                 mm = f[j];
30                 p = j;
31             }
32         vis[p] = 1;
33         for (int j=1;j<=n;j++)
34             if(!vis[j] && mp[p][j] && f[p] + mp[p][j] < f[j])
35             {
36                 f[j] = f[p] + 1;
37             }
38     }
39     return ;
40 }
41 int solve()
42 {
43     int A = 1, B = 2, C = 3;
44     spfa(A,dis[A]);
45     spfa(B,dis[B]);
46     spfa(C,dis[C]);
47
48     int res  = -1;
49     for (int d = 1;d<=n;d++)
50     {
51         if (dis[A][d]< 100000&& dis[B][d]!=100000 && dis[C][d]!=100000)
52         {
53             int tmp = dis[A][d] + dis[B][d] + dis[C][d] - 2;
54             if (res == -1 || tmp < res)
55             {
56                 res = tmp;
57             }
58         }
59     }
60     return res;
61 }
62 int main()
63 {
64     int cas;
65     scanf("%d",&cas);
66     while (cas--)
67     {
68         scanf("%d", &n);
69         for (int i=1;i<=n;i++)
70         {
71             scanf("%d%d%d", &sq[i].x, &sq[i].y, &sq[i].r);
72         }
73         for (int i=1;i<=n;i++)
74         {
75             for (int j=1;j<=n;j++)
76             {
77                 mp[i][j] = calc(i,j);
78             }
79         }
80         int ans = solve();
81         if (ans == -1)
82             printf("%d\n",ans);
83         else{
84             printf("%d\n", n - ans);
85         }
86     }
87     return 0;
88 }

E(wangsouc)

期间我读了D题,和niuniu讨论,此题是lcs的变形,我认为是可做的,让niuniu分析分析。

【然后我又继续YY F题】,我换用了C语法,使用C提交,居然AC了!时间2671ms,然后我把之前那个使用c++提交,也过了2671ms。235min,3A。

跪:G++、C++、GCC,在运行上确实差异很多,C++运行要快,G++读写快。

 1 #include <stdio.h>
 2 #include <string.h>
 3
 4 #define maxn 10005
 5
 6 int seq[maxn];
 7 int hash[maxn];
 8 int n;
 9 bool calc()
10 {
11     int d, i,tmp = n;
12     for (d = 1;d<=n/2;d++)
13     {
14         tmp -= 2;
15         for (i=1;i<=tmp;i++)
16         {
17             if (hash[i] < hash[i+d] && hash[i+d] < hash[i+ d+ d])
18             {
19                 return true;
20             }
21             if (hash[i] > hash[i+d] && hash[i+d] > hash[i+ d+ d])
22             {
23                 return true;
24             }
25
26         }
27     }
28     return false;
29 }
30 int main()
31 {
32     int T,i,x;
33     scanf("%d", &T);
34     while(T--)
35     {
36         scanf("%d", &n);
37         for(i = 1; i <= n; i++)
38         {
39             scanf("%d", &x);
40             hash[x] = i;
41         }
42         if (calc())
43             puts("Y");
44         else
45             puts("N");
46     }
47     return 0;
48 }

F(wangsouc + niuniu)

【B】然后lh大仙有想法要写B题,就交电脑给他coding。

居然不知不觉把B给过了,243min A掉。太神奇了有没有!!原来是对人进行建图。是个好题啊。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cmath>
 5 #include <string.h>
 6 #include <string>
 7
 8 using namespace std;
 9
10 const int MAXN = 500 + 10;
11 int n, m, k;
12 int c[MAXN][MAXN];
13 bool vis[MAXN];
14 int match[MAXN];
15
16 bool dfs(int u)
17 {
18     for (int i = 0; i < k; i++)
19     {
20         if (!vis[i] && c[u][i])
21         {
22             vis[i] = true;
23             if (match[i] == -1 || dfs(match[i]))
24             {
25                 match[i] = u;
26                 return true;
27             }
28         }
29     }
30
31     return false;
32 }
33
34 void solve()
35 {
36     int res = 0;
37
38     for (int i = 0; i < k; i++)
39     {
40         memset(vis, false, sizeof(vis));
41         if (dfs(i))
42         {
43             res++;
44         }
45     }
46     printf("%d\n", k - res / 2);
47 }
48
49 struct Node
50 {
51     string a, b;
52 }node[MAXN];
53
54 void input()
55 {
56     while (scanf("%d %d %d", &n, &m, &k) != EOF)
57     {
58         int a, b;
59         memset(c, 0, sizeof(c));
60         memset(match, -1, sizeof(match));
61         for (int i = 0; i < k; i++)
62         {
63             cin >> node[i].a >> node[i].b;
64         }
65
66         for (int i = 0; i < k; i++)
67         {
68             for (int j = 0; j < k; j++)
69             {
70                 if (node[i].a == node[j].b)
71                 {
72                     c[i][j] = c[j][i] = 1;
73                 }
74             }
75         }
76
77         solve();
78     }
79 }
80
81 int main()
82 {
83     input();
84     return 0;
85 }

B(lihe)

后面又和lh讨论了A题,大意,给定N<=16个数,进行二进制形式链接(重合部分可以重叠),求连接之后最小的串。我的第一直觉是TSP问题,不过那个最小值和后缀不好维护啊,现在我也不会。后面想想AC自动机维护后最,YY半天不会弄。

【转而搞D】,大意,给定A串和B串,进行操作:删除\插入\替换(编辑距离),然后是可以改变后缀如abcdefg变为abcddddd(显然倒序之后就是改变前序)。

和niuniu讨论了很久,标准的lcs模型,niuniu想不清楚公式:

f[i-1][j] + 1 ->f[i][j](删除第i个)

f[i][j-1] + 1 -> f[i][j](添加第j个)

f[i-1][j-1] + (A[i] != B[j])->f[i][j](不同就change)

估计是脑容量不够用了,一般比赛这个时候都是体力脑力精力透支啊!

我设计了空间和时间都是O(52*N*M),N、M<=500,的算法。大概算了算需要125*10^5个int型,第一反映是会MLE。没写。

最后20分钟,dongfang队走了,lh大仙也跟着走了,我和niuniu闲得没事就搜了搜,发现正解就开了52*N*N的数组。

我坚定的要写D,niuniu在一旁帮我看着(她这个时候应该已经理解转移公式了)

最后还剩下10min,我写完提交MLE,原来数组开成55*555*555了,我改掉成55*51*51提交WA。

后面才发现A串长度和B串不一样,改掉提交WA。

我知道f[k][i][j]也需要考虑前缀变换,于是加上提交,AC! 312min,5A。

太激动了有没有!

然后,我把比赛时间加了30min。掉人品啊!

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 #include<algorithm>
  5
  6 using namespace std;
  7
  8 const int maxn = 501;
  9 char str[maxn];
 10 const int inf = 0x3f3f3f3f;
 11 int A[maxn];
 12 int B[maxn];
 13 int n;
 14 int m;
 15 int dp[maxn][maxn];
 16 int f[53][maxn][maxn];
 17 int get_id(char ch)
 18 {
 19     if (ch<='Z' && ch>='A')
 20         return ch - 'A';
 21     return 26 + ch - 'a';
 22 }
 23
 24
 25
 26 void init()
 27 {
 28     memset(f,-1, sizeof(f));
 29
 30     for (int k=0;k<52;k++)
 31     {
 32         for (int i=0;i<maxn;i++)
 33         {
 34             f[k][0][i] = i;
 35             f[k][i][0] = i;
 36         }
 37     }
 38
 39     for (int i=1;i<=n;i++)
 40     {
 41         for (int j=1;j<=m;j++)
 42         {
 43             for (int k=0;k<52;k++)
 44             {
 45                 f[k][i][j] = f[k][i-1][j] + 1;
 46                 f[k][i][j] = min(f[k][i][j], f[k][i-1][j-1] + (k != (int)B[j]));
 47                 f[k][i][j] = min(f[k][i][j], f[k][i][j-1] + 1);
 48                 f[k][i][j] = min(f[k][i][j], f[B[j]][i-1][j] + 1 + (k!=B[j]));
 49                 f[k][i][j] = min(f[k][i][j], f[B[j]][i-1][j-1]  + (k!=B[j]));
 50                 f[k][i][j] = min(f[k][i][j], f[B[j]][i][j-1] + 1 + (k!=B[j]));
 51             }
 52         }
 53     }
 54     return ;
 55 }
 56 int main()
 57 {
 58 //    printf("%d\n",get_id('Z'));
 59     while (scanf("%s",str))
 60     {
 61         if (str[0]=='#')
 62             break;
 63         n = strlen(str);
 64         for (int i=1;i<=n;i++)
 65         {
 66             A[i] = get_id(str[n - i]);
 67         }
 68         scanf("%s",str);
 69         m = strlen(str);
 70         for (int i=1;i<=m;i++)
 71         {
 72             B[i] = get_id(str[m-i]);
 73         }
 74
 75         init();
 76
 77
 78         for (int i=0;i<=n;i++)
 79         {
 80             for (int j=0;j<=m;j++)
 81             {
 82                 dp[i][j] = inf;
 83             }
 84         }
 85
 86         for (int i=0;i<maxn;i++)
 87         {
 88             dp[0][i] = i;
 89             dp[i][0] = i;
 90         }
 91         for (int i=1;i<=n;i++)
 92         {
 93             for (int j=1;j<=m;j++)
 94             {
 95                 dp[i][j] = dp[i-1][j] + 1;
 96                 dp[i][j] = min(dp[i][j], dp[i][j-1] + 1);
 97                 dp[i][j] = min(dp[i][j], dp[i-1][j-1] + (A[i] != B[j]));
 98                 int tmp = inf;
 99                 for (int k=0;k<52;k++)
100                 {
101                     tmp = min(tmp, 1 + f[k][i][j]);
102                 }
103                 dp[i][j] = min(dp[i][j], tmp);
104             }
105         }
106         printf("%d\n",dp[n][m]);
107     }
108     return 0;
109 }

D(wangsouc+niuniu)

总结:

0、我和niuniu迟到近50min,是绝对错误的,以后的比赛,不会再迟到。

1、lh大仙深深的陷入了B题,拉住了全场。I题虽过,掉人品的。

2、所有题目还属于比较轻松的,English要求也不高,我读了其中的B\C\D\F\H\I,其中A\C题没读懂,所有题目都被读了。但是,C\G没有讨论。

3、题目难度属于中等偏下的难度,和省赛难度差不多,多校训练里算最简单的了。

4、目前组队比赛,分工还不明确,讨论不够,比如(lh和niuniu经常都没讨论),而我基本要和两个都讨论;这点,需要加大知识面的交集和题目阅读的交集。

5、niuniu编码能力有待提高,应该有做到自己的算法自己能实现,特别是水题。

6、在图论、DP方面,3个人都应该要多学学,这样才会有讨论的交集,很重要!

7、以后下来还是要多下来讨论总结。

加油!

转载于:https://www.cnblogs.com/wangsouc/articles/3691904.html

20140426组队赛总结相关推荐

  1. nyist --- 组队赛(四)

    本次已是第四次组队赛了,感觉状态不太好,队友之间配合的不是那么默契,A,B,C,G,F,H题都是比较水的题目,不过在做题的过程中 总是让人感觉出乎意外,第一题即wa了一次,紧接着第二题wa了3次,英文 ...

  2. 省赛组队赛3 比赛总结

    比赛链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=44451#overview 今天下午又做了一次组队赛练习,大部分队都是做出了5道 ...

  3. 2012暑假最后两次组队赛总结

    最后两次组队赛的题都相对简单,所以两次都得到较高的题目数!一次是在hdu的diy上做,另外的是在bnu做spoj的题. 先补回倒数第二场的总结. 倒数第二场一共有10题,当时过的题包括一题枚举求最大值 ...

  4. hdu区域赛在线热身赛 暨 第十二场组队赛

    题目编号:hdu 4257~4266 (对应比赛题号1001~1010) 这是我们第十二场组队赛,在今天中午进行. 比赛刚开始,依然是由我的队友读题.还没看几题,就发现了好多题judge时长高达20秒 ...

  5. acm省赛选拔组队赛经验谈

    省赛组队赛已经进行5场了,过半了. 从曾经的不会组队到如今逐渐磨合,尽管每次都有遗憾,可是我认为我们一直在进步.有些失误是要记录下来下次不能再犯的! 经验: 1:上场開始一定要有人(英语能力和算法综合 ...

  6. 2019组队赛第二场(ACM International Collegiate Programming Contest, Arabella Collegiate 解题报告 Apare_xzc

    2019组队赛第二场(ACM International Collegiate Programming Contest, Arabella Collegiate 解题报告 by xzc,zx,lj 先 ...

  7. HHTC_学校集训编程题目(13)(组队赛_3)

    HHTC_学校集训编程题目(13)(组队赛_3) C - Wandering Robot G - Circle B - 迷宫寻宝 D - 给力的移动 E - 谁还不是个宝宝 K - Teamwork ...

  8. HHTC_学校集训编程题目(11)(组队赛_1)

    HHTC_学校集训编程题目(11)(组队赛_1) B - Problem B. Memory Banks A - 小妖的下属 C - 巴啦啦能量 E - 貂蝉的试炼 F - 一品五彩棒 H - 丢失的 ...

  9. HPU组队赛B:问题(二进制枚举)

    时间限制1 Second 内存限制 512 Mb 题目描述 你有n个问题,你已经估计了第i个问题的难度为Ci,现在你想使用这些问题去构造一个问题集.比赛的问题集必须包含至少两个问题,而且比赛的总难度必 ...

最新文章

  1. mysql求每个订单的平均价_MySQL – 选择所有客户和每个客户的总订单和总价值
  2. centos下ftp接受/发送文件
  3. SAP S/4HANA Analytics Path Framework 里过滤器(filter)的使用方法介绍
  4. zoj 3488 conic section
  5. 【华为云技术分享】《跟唐老师学习云网络》—ARP你在哪
  6. [FFmpeg] CMake 单独编译 ffplay 之基础篇
  7. 九度OnlineJudge之1001:A+B for Matrices
  8. 记一次360面试总结(Android)
  9. stm32呼吸灯程序_STM32寄存器操作点亮LED灯
  10. 如何写python程序
  11. Java代码注释加入图片和表格
  12. python所有字母大写_在python中将所有字母改为大写
  13. 微信小程序实现瀑布流 仿小红书
  14. 深度学习_深度学习基础知识_Internal Covariate Shift
  15. GoldWave 音频截取工具
  16. w7桌面计算机图标打不开了,桌面图标打不开,教您桌面图标打不开怎么办
  17. 第一章 初识Java总结
  18. 记一次.Net Core通过GDI+在CentOS 7(Docker)环境中绘图报错The type initializer for ‘Gdip‘ threw an exception的问题及处理方式
  19. H3C无线接入器WA4320-ACN-SI之FIT转FAT(瘦版本转胖版本)
  20. 电梯门禁系统服务器一般在哪,别被吓住了,电梯门禁(梯控)安装其实并不难...

热门文章

  1. 《当程序员的那些狗日日子》(二十八)开展新工作
  2. inter 实感技术
  3. 秋招—文思海辉笔试题
  4. 翻译并添加 解析OV13850 datasheet
  5. 超越 ConvNeXt、RepLKNet | 看 51×51 卷积核如何破万卷!
  6. 论文笔记《Are You Talking to Me? Reasoned Visual Dialog Generation through Adversarial Learning》
  7. 5000英镑就可买到控制美国核武库的同款IBM电脑
  8. springboot+thymeleaf实例
  9. 《深度强化学习实践》学习内容整理
  10. android实习日志_Android实习的个人总结