您的位置:首页 > 其它

周赛G题 华山论剑

2013-10-23 22:16 113 查看
题目链接:点击打开链接

这题也是我TLE中的一个,一开始我想到的是并查集,但是为什么会想到并查集,可能是最近又一次的搞过并查集。但是,很是脑残的是一直RE,就是找不出为什么会这样。然后就一直改改改,直接改成TLE了,很是郁闷。就有给放弃了。

附上RE代码:

//RE----------------------
#include<cstdio>

const int N=300005;
int n,m,father
;

void Init()
{
    for(int i=1;i<=n;i++)
        father[i]=i;
}

int find(int x)
{
    if(x!=father[x])
        father[x]=find(father[x]);
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        Init();
        int l,r,xi;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&l,&r,&xi);
            for(int j=l;j<=r;j++)
            {
                if(j!=xi)
                {
                    int Xfather=find(j);
                    if(Xfather==j)
                        father[j]=xi;
                }
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(i==n)
            {
                if(father[i]==i) printf("0\n");
                else printf("%d\n",father[i]);
            }
            else
            {
                if(father[i]==i) printf("0 ");
                else printf("%d ",father[i]);
            }
        }
    }
    return 0;
}


后来看题解,我笑了,确实是并查集,但是维护father数组,很是有特点,而且有学会了并查集的一种用法,快速查找的功能。很是巧妙。

附上AC代码。

#include<cstdio>

const int N=300005;
int n,m,father
,ans
;

int find(int x)
{
    if(x!=father[x])
    father[x]=find(father[x]);
    return father[x];
}

void Init()
{
    for(int i=0;i<=n+1;i++)
    father[i]=i,ans[i]=0;
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        Init();
        int l,r,xi;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&l,&r,&xi);
            //-----------------------------
            //快速查找区间上的存活人员.
            for(int j=find(l);j<=r;j=find(j+1))
            {
                if(j==xi) continue;
                ans[j]=xi;
                //-----------------------
                //不好理解的估计就是这儿了.怎样维护father数组
                if(j<xi) father[j]=xi;
                else father[j]=father[r+1];//可以直接查找到下一个没有被杀的.
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(i==n) printf("%d\n",ans[i]);
            else printf("%d ",ans[i]);
        }
    }
    return 0;
}


由此题可以看出,有时候思路是正确的,只是自己的一些处理方法不对,如果进一步的思考可能会有思路。深入思考,这是更好的方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: