周赛事总结

来源:互联网 发布:怎样经营网络棋牌室 编辑:程序博客网 时间:2024/04/28 12:27

周赛事总结

所学新知识:

NO.1并查集(好东西):

简要概括:

就是将数据封装在了一棵树里,每次查询只需要将每个节点的父亲标记为根节点就好了!
比如:
这里写图片描述
就变成了:
这里写图片描述

代码:

#include <iostream>#include <stdio.h>#include <cstring>using namespace std;const int N=100005;int f[N],size[N];int n,m;void init (){    for(int i=1; i<=n; i++)        f[i]=i,size[i]=1;}int find(int a){    return f[a]==a?a:f[a]=find(f[a]);}int add(int a,int b){    if(size[a]<size[b])    {        f[find(a)]=f[find(b)];        size[b]+=size[a];    }    else    {        f[find(b)]=f[find(a)];        size[b]+=size[a];    }}bool judge(int a,int b){    if(find(a)==find(b))        return true;    return false;}int main(){    scanf("%d%d",&n,&m);    init();    for(int i=1; i<=m; i++)    {        int x,y,z;        scanf("%d%d%d",&z,&x,&y);        if(z==1)            add(x,y);        else        {            if(judge(x,y))                printf("Y\n");            else                printf("N\n");        }    }    return 0;}

NO.2 KMP

解释:

详情请见:
KMP专题

代码:

#include <iostream>#include <stdio.h>#include <map>#include <cstring>using namespace std;const int N=100005;int p[N];char s[N],t[N*10];void getp(int n){    p[0]=-1;    for(int i=1,j=-1; i<=n; i++)    {        while(j>=0&&s[j+1]!=s[i])        {            j=p[j];        }        p[i]=++j;    }}int KMP(int n,int m){    int ret=0;    for(int i=1,j=0; i<=m; i++)    {        while(j>=0&&s[j+1]!=t[i])        {            j=p[j];        }        j++;//ºóɨһλ!!         if(j==n)        {            ret++;            j=p[j];        }    }    return ret;}int main(){    int n;    scanf("%d",&n);    while(n--)    {        scanf("%s",s+1);        int n=strlen(s+1);        getp(n);        scanf("%s",t+1);        int m=strlen(t+1);        printf("%d\n",KMP(n,m));    }}

NO.3单源最短路径

解释:

详情请见:
最短路

NO.4归并排序:

解释:

就是利用二分的思想,对于一串数字的左边经行排序,右边也同时进行排序,最后再用O(N)的复杂度去合并数字,所以总的复杂度是O(n logn)!

代码:

(照着别人的代码打了一遍…)

#include <iostream>#include <algorithm>#include <stdio.h>#include <cstring>using namespace std;const int N=100005;int date[N],result[N];void merge(int *date,int start,int end,int *result){    int left_length=(end-start+1)/2+1;    int left_index=start;//´ÓÒ»²¿·Ö µÄ ¿ªÊ¼    int right_index=start+left_length; //´ÓµÚ¶þ²¿·ÖµÄ Í·¿ªÊ¼    int result_index=start;    while(left_index<start+left_length&&right_index<=end)    {        if(date[left_index]<=date[right_index])            result[result_index++]=date[left_index++];        else            result[result_index++]=date[right_index++];    }    while(left_index < start+left_length)        result[result_index++]=date[left_index++];    while(right_index < end+1)        result[result_index++] =date[right_index++];}void merge_sort(int *date,int start,int end,int *result){    if(1==end-start)    {        if(date[start]>date[end])            swap(date[start],date[end]);        return ;    }    if(0==end-start) return ;    else    {        merge_sort(date,start,start+(end-start+1)/2,result);        merge_sort(date,start+(end-start+1)/2+1,end,result);        merge(date,start,end,result);        for(int i = start; i <= end; ++i)            date[i] = result[i];    }}int main(){    int n;    scanf("%d",&n);    for(int i=1; i<=n; i++)        scanf("%d",&date[i]);    printf("now the order is:\n");    for(int i=1; i<=n; i++)        printf("%d ",date[i]);        printf("\n");    merge_sort(date,1,n,result);    printf("after mergesort ...\n");    for(int i=1; i<=n; i++)        printf("%d ",date[i]);    return 0;}

心路总结:

知识点总结:

1.学会很好的初始化,一定要注意数据范围在判断
因为初始化实在是太重要了!不然程序怎么错的都不知道!

2.可以根据数据范围来判断算法的复杂度
3.就是数据初始化的问题导致
4.学会简化问题
5.不去紧张和看重Rank比分!
6.加强数学证明题的思路
7.慢慢来,不着急
8.学会向上取整 ,不要每次都错在的了最小的细节上!
9.学会推数学公式,但是不要取模太小了!
10.稳住,比赛的时候最好不要着急,因为你如果急了,你真的就完蛋了!
11.数论知识!
12.爱上信息,不怕难!

原创粉丝点击