一.codeforces比赛小结
C. Most Similar Words

  这次的比赛前两道题比较简单,很快就A了,在此就不多说。
第三题比较有意思,开始时以为这道题会有什么规律,但就是找不到,无奈之下只能用笨法子,枚举求解,不过还好做出来了。

题解:
  每两个序列求一次差,最后比较输出最小的差。

代码

#include <bits/stdc++.h>
using namespace std;
int t;
int n,m;
char a[55*10][55*10];
int b[1250];
int sum(int x,int y,int m)
{  int q=0,s;
  for(int i=0;i<m;i++)
    {s=abs(a[x][i]-a[y][i]);
    q+=s;}
  return q;
}
int main()
{  cin>>t;
   while(t--)
   { int i,j;
     cin>>n>>m;
     for(i=0;i<n;i++)
      {for(j=0;j<m;j++)
      {cin>>a[i][j];}}
      int k=0;
      for(i=0;i<n-1;i++)
      for(j=i+1;j<n;j++)
      {b[k]=sum(i,j,m);k++;}
      sort(b,b+k);
      cout<<b[0]<<endl;
   }
}

说一下几次CF下来的感受:

1.越来越适应比赛了,从开始的读不懂题,不敢下手,到后来的比赛一开始就抓紧读题,快速找到思路,然后A题,能很明显感受到自己的进步。对于比赛的步骤也越来越熟悉,面对比赛也不会有太大的紧张感,心态越来越稳定。

2.再有就是思维的提升。之前看到思维题我都会头疼,因为没有思路,但现在拿过一个思维题,我能理顺其逻辑,快速的找到思路然后求解,思维题反而成了我比较擅长的题型,这是我最大的一个收获。

3.打CF后看别人的题解是个很好的提升自己的途径。看看实力强的人是怎样写代码的,他们的思路是怎样的,代码是如何组织的,尽量消化吸收让其成为自己的东西,多领悟领悟真的会收获很多。

4.打CF以来,排名由最后几名慢慢往前靠,看着自己一点点进步真的很有满足感,有时候就算排名低也不会难过,只会增强我的好胜心,激起我的干劲,感觉自己越来越适应且喜欢这种比赛的氛围了。

二、
P1547 [USACO05MAR]Out of Hay S 题意:输出最小生成树中的最长边的长度。

题解:kruskal算法,将边按权值从小到大排序后逐个判断,如果当前的边加入以后不会产生环,那么就把当前边作为生成树的一条边,得到最小生成树后输出最长边的长度。(基本上是套用kruskal模板)
  是个很好的模板题,简单整理一下。

代码

#include <iostream>
#include <queue>
using namespace std;
const long MAXN=10000;
long father[MAXN];
long m,n;
typedef struct
{
    long from;
    long to;
    long cost;
}Edge;

bool operator <(const Edge &a, const Edge &b)
{
    return a.cost>b.cost;
}
priority_queue<Edge> q;
Edge e;
void MakeSet()
{
    long i;
    for (i=0;i<=m;++i)
    {
        father[i]=i;
    }
}
long Find(long i)
{
    long r=i;
    while (father[r]!=r)
    {
        r=father[r];
    }
    while (father[i]!=r)
    {
        long j=father[i];
        father[i]=r;
        i=j;
    }
    return r;
}
void Unition(long x,long y)
{
    long fx=Find(x);
    long fy=Find(y);
    if (fx!=fy)
    {
        father[fx]=fy;
    }
}
void print(long cost)
{
    printf("%ld\n",cost);
}
void Init()
{
    while (!q.empty())
    {
        q.pop();
    }
    MakeSet();
    long i;
    for(i=0;i<n;++i)
    {
        scanf("%ld %ld %ld",&(e.from),&(e.to),&(e.cost));
        q.push(e);
        swap(e.from,e.to);
        q.push(e);
    }
}
void Kruskal()
{
    Init();
    long t=0;
    Edge z=q.top();
    long cost=z.cost;
    Edge e;
    while (!q.empty()&&t<m-1)
    {
        e=q.top();
        long v1=e.from;
        long v2=e.to;
        if (Find(v1)!=Find(v2))
        {
            Unition(v1,v2);
            if(e.cost>cost) cost=e.cost;
            ++t;
        }
        q.pop();
    }
    print(cost);
}

int main()
{
    while(scanf("%ld %ld",&m,&n)!=EOF)
    {
        Kruskal();
    }
    return 0;
}

P3958 [NOIP2017 提高组] 奶酪

题意:相连的洞可以看作一个集合,问能否从下表面走到上表面。

题解:可用并查集,两点之间的距离小于等于2r即可合并,合并时将z值大的设为根节点,所有点合并完后得到数个集合,判断集合中最下方和最上方的洞是否接触下表面和上表面(即最底下的结点满足z-r小于等于0,根节点满足z+r大于等于h),若是则yes,否则No。 (之前用搜索做的,学了并查集后感觉并查集更好写,果然会的越多,方法越多)

P1197 [JSOI2008]星球大战

题意:每去掉一个点,判断以此是否连通。

题解:先建立集合再删点比较麻烦,可以倒着来,先删去该点,看剩下点构成集合的个数输出。   正难后易,正着走行不通,那就倒着来,思维要灵活一点。

P2078 朋友

  开始时用负下标存数组存放结点,结果一直报错,直到看题解,看到一种存储结点的方式为法 f [1] - f [n]存放A公司结点, f [n+1] - f[n+m]存放B公司结点,很有用,改成这个后我就A了。这种方式对存放两套 f [ i ]很管用,在此稍稍整理。

三、收获心得
1.这几周以来学到了不少新知识,例如STL,搜索,图论,并查集,拓扑排序,最小生成树等等。知识储备增加了,知识面也拓宽了很多,我才发现原来有这么多有趣好用的算法,原来我会的还只是区区一角,原来我要走的路还很长,不能仅仅满足于课本,不要做井底之蛙,我还要不断学习。

2.我的学习习惯变好了。之前写东西只是做到了背过会用,理解不深,而现在我写东西注重理解,掌握的东西更加牢固,用的更顺手,让其成为了自己的知识。我尽量养成每天看博客的习惯,每天提升一点,总有一天会积少成多。

3.这段时间的学习告诉我们只看不做是不会有收获的,唯有动手才有进步,只听过越用越顺手,没听过越看越顺手。只有动手去做才能真正发现自己的问题所在,不要浮于表面,要脚踏实地。

4.遇事不要拖,当前有空一定要当前做,不要寄希望于后几天。尤其是现在,课程多,时间紧,任务重,你无法确定后几天有没有事情。真到事情堆一块的时候就晚了,所以下手要趁早。

5.要想把一件事做成功,就得全神贯注,就得集中精力,三心二意是不可取,否则容易一事无成。打定主意做一件事就专心去做,少惦记这惦记那,不能捡了西瓜丢了芝麻。

5.经过不断的摸索,我有了自己的一套查错误的做法。若一道题出现wa,首先我会检查细节,如数组是否溢出,数据容量是否足够大,是不是英文输出,有没有漏掉头文件等等,若还是没A过,我就会在纸上走一遍程序,看看自己的思路是否有不完善的地方,若有怎么改进,或者我在每一小部分的操作后加上输出,检查这步操作是否按所想进行,以此找错。

6.我学着跳出自己的舒适圈去挑战自己,我想有些改变,我想借此机会试试看,看看自己会如何进步,看看自己会如何改变,看看能否收获一个不一样的自己。