回 帖 发 新 帖 刷新版面

主题:第40次编程比赛结果

第1题 主要是集合查询和合并。合并的效率很重要,如果能想到并查集,那么做起来就不难,代码量也不大。本来第1题想出图论的,又怕控制不好难度,不过并查集跟树挂钩,也勉强算是图论吧。给出一段代码供参考:
int root(int v,int* set)
{
    if (set[v] == v) return v;
    return set[v]=root(set[v],set);
}

int ReligionsStd(int n,int m,int* record)
{
    int i,count=n;
    int* set=new int[n+1];

    for (i=0;i<=n;i++) //初始化
        set[i]=i;
    for (i=0;i<m*2;i+=2)
        if (root(record[i],set)!=root(record[i+1],set))//如果属于不同集合
        {
            set[set[record[i]]]=set[record[i+1]];//合并
            count--;
        }

    delete[] set;
    return count;
}


  第1轮:
  fstream fout ("filename");
  n=50000;
  m = [color=FF0000]t[/color] -1;
  fout<<"1 2"<<endl;
  for (i=3;i <= [color=FF0000]t[/color];i+=2)
    fout<<i<<' '<<i+1<<endl<<i<<' '<<i-1<<endl;
  测试数据由上面的代码生成,[color=FF0000]t[/color]=20,200,2000,20000,50000,这是针对性的数据,如果集合合并效率不高,用这组数据是很痛苦的。本来只是是想测试速度,但很多人的程序都出错了。正确结果依次是49981,49801,48001,30001,1。

1 jackin0627: >10s
2 天边蓝:错误
3 iAkiak: 47ms 
5 liyanguestc: 错误 
6 joekings:0ms
7 liangbch:错误
8 Cyre:错误
10 yelv:错误
11 joekings: 0ms
12 zheni: 7922ms
13 xiaopangzi:错误
14 wlsss: >10s
15 BigCarrot: <15ms
16 rickone: <15ms
17 孤独的猫:>10s
18 boxertony:Runtime Error
19 NingYusui:错误
20 xyhx:错误
21 eastcowboy:0ms
22 babyzn:错误
23 jfs771:错误
24 hwjian:错误
25 火海时代:错误
26 wshong:>10s

第2轮:
joekings和eastcowboy的程序快的出奇,但很遗憾算法不对。用一组简单的数据可以测出错误。
n=3 m=2
record={1 3 2 3}

第3轮:
12 zheni: >10s
3 iAkiak: 100ms 
15 BigCarrot: 37ms
16 rickone: 68ms
多组数据测试,以上3位算法没有本质的差别,但BigCarrot实现的最快。iAkiak用模板在速度上可能有些吃亏。



第2题:第2题是简单博弈论题,实现起来很方便,大家做的正确率也很高。
2 boxertony:0ms
3 joekings:0ms
6 liyanguestc:0ms
7 BigCarrot:0ms
8 孤独的猫:0ms
9 wlsss:0ms
14 forjane:0ms
17 xyhx:0ms

5 ITER:错误
10 hainanlion:错误
11 hwjian: 错误(30位,longlong不够)
12 magicalking:错误 long更不够
13 liangbch:超时


综合以上2题的结果,第40次编程比赛的冠军是[color=FF0000]BigCarrot[/color],恭喜他。

如果对测试结果有任何异议,请尽快跟帖,我会认真复查。

回复列表 (共44个回复)

41 楼

[quote]我人工测的,测函数返回值,怎么会有PE?
你测下2和12。

你程序当中这一段是多余的,导致出错。
if(1==lena||1==lenb)
{
&nbsp;&nbsp;&nbsp;&nbsp;if('1'==*a||'1'==*b)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true;
}
[/quote]
哦  晕  是的  哈哈  是多余的
要写也应该两个分别判断不能合起来 
终于领教了"画蛇添足"这个成语...

谢谢哈 "neverPE"兄   :)

42 楼


int Religions(int n,int m,int *record)
{ int i,j=0,k,k1=1,count,flag=0;
  int data[5000];
  int b[100][2];
  for(i=0;i<2*m&&j<m;i+=2)
   {b[j][0]=record[i];
    b[j][1]=record[i+1];
     j++;}

 data[0]=b[0][0];
  data[1]=b[0][1];
  k=2;count=1;
  for(;k1<m;k1++)
 { for(i=0;i<k;i++)
   {if((b[k1][0]==data[i])||(b[k1][1]==data[i]))
     {if(b[k1][0]==data[i]&&data[i+1]!=b[k1][1]&&i+1<k)
    {data[k]=b[k1][1];k++;flag=1;printf("\n%d\n",data[k-1]);break;}
      else if(b[k1][1]==data[i]&&data[i+1]!=b[k1][0]&&i+1<k)
       {
       data[k]=b[k1][0];k++;flag=1;printf("\n%d\n",data[k-1]);break;}

     }
   }
  if(!flag){data[k]=b[k1][0];data[k+1]=b[k1][1];k=k+2;count++;}}

count=count+n-k;
return count;}



//错过了  发来麻烦楼主给看下

43 楼


上面的5000改成50000

44 楼

#include<stdio.h>
#include<stdlib.h>
typedef struct
{
    int first;
    int root;
}Node;
int Religions(int n,int m,int* record)
{
    Node *num;
    num=(Node*)malloc((n+1)*sizeof(Node));
    for(int i=0;i<=n;i++)
    {
        num[i].first=n;
        num[i].root=i;
    }
    for(i=0;i<m;i++)
    {
        int a=record[2*i];
        int b=record[2*i+1];
        if(num[a].root==num[b].root)
            continue;
        num[a].first=(num[a].first<2*i)?num[a].first:2*i;
        num[b].first=(num[b].first<2*i+1)?num[a].first:2*i+1;
        if(num[a].first<num[b].first)
            num[b]=num[a];
        else
            num[a]=num[b];
        --n;
    }
    return n;
}

我来回复

您尚未登录,请登录后再回复。点此登录或注册