回 帖 发 新 帖 刷新版面

主题:第40次编程比赛第1题题目

考虑到这次有2题,而且我明天中午也许不能上线。提前一点放出来,结束时间不变。

    有n个学生. 每个学生都有自己的宗教信仰,可能相同,也可能不同。一个调查机构想弄清楚宗教信仰的总数。但是,直接询问可能会使人不快,于是,调查机构决定询问m对学生,问他们是否具有相同的宗教信仰。(如果相同,则他们会参加同一教会,彼此会认识)。要求计算最大可能的宗教数。

函数原型 int Religions(int n,int m,int* record);

n            人数 1<=n<=50000
m            抽查的学生对数,record中有2m个学生编号。 0<=m<=n*(n-1)/2 且 m<=500000
record[]     编号record[i*2]与record[i*2+1]的两个学生,他们之间有相同的信仰。0<=i<m,学生编号1~n
返回值:最大可能的宗教数。

内存限制:256M 
时间限制:10S

样例:
n=10 m=9
record[]=
{1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10}
返回值:1

n=10 m=4
record[]=
{2 3
4 5
4 8
5 8}
返回值:7


一点提示:不要想太复杂了。

回复列表 (共29个回复)

沙发

int Religions(int n,int m,int* record)
{
    int *f=new int[n+1];
    int i,j,count=0,s=1;

    memset(f,0,(n+1)*sizeof(int));
    for(i=0;i<2*m;i+=2)
    {
        if( f[record[i]]==0 && f[record[i+1]]==0 )
        {
            f[record[i]]=s;
            f[record[i+1]]=s++;
            count++;
        }
        else if(f[record[i]]!=0 && f[record[i+1]]==0 )
        {
            f[record[i+1]]=f[record[i]];
            count++;
        }
        else if(f[record[i]]==0 && f[record[i+1]]!=0 )
        {
            f[record[i]]=f[record[i+1]];
            count++;
        }
        else if(f[record[i]] != f[record[i+1]])
        {
            for(j=0;j<n;j++)
            {
                int t=f[record[i+1]];
                if(f[j]==t)
                {
                    f[j]=f[record[i]];
                }
            }
            count++;
        }
    }
    return n-count;
}

板凳

int data[50000];
int Religions(int n,int m,int* record){
    int count=0;
    for(int i=0;i<n;i++)
    data[i]=1;
    for(int i=0;i<m;i++){
        if(data[ record[2*i] ]==1&&data[ record[2*i+1] ]==1){
            count++;
            data[ record[2*i] ]=0;
            data[ record[2*i+1] ]=0;
        }
        else{
            data[ record[2*i] ]=0;
            data[ record[2*i+1] ]=0;
        }
    }
    for(i=0;i<n;i++)
        count+=data[i];
    return count;
}

3 楼

改一下,不直接用ufset,原连接不需要保存,把结点尽量直接指向祖先结点减少以后查询的深度。
#include <cstdio>
#include <cassert>
#include <vector>

using namespace std;

struct UFSet
{
    UFSet(int count) :
    parent(count + 1, 0), island(count)
    {
    }
    int island;
    void Union(int a, int b)
    {
        int la, lb;
        int sa = Find(a, la), sb = Find(b, lb);
        if (sa == sb)
            return;
        if (la > lb)
        {
            parent[sb] = sa;
            if (a != sa)
                parent[a] = sa;
            parent[b] = sa;
        }
        else
        {
            parent[sa] = sb;
            if (b != sb)
                parent[b] = sb;
            parent[a] = sb;
        }
        island--;
    }
    int Find(int a, int &len)
    {
        assert(a > 0 && a < parent.size());
        len  = 0;
        while(parent[a] > 0)
            a = parent[a], len++;
        return a;
    }
    vector<int> parent;
};
int Religions(int n,int m,int* record)
{
    UFSet s(n);
    int i;
    for (i = 0; i < m; i++)
    {
        s.Union(record[i*2], record[i*2+1]);
    }
    return s.island;
}

4 楼

走了, 大家编程去啦~~~~~

5 楼

#include <iostream>
using namespace std;
int Religions(int n,int m,int* record);
int main()
{int n,m;
static int a[500000];
freopen("c:\\in.txt","r",stdin);
cin>>n>>m;
for(int i=0;i<2*m;i+=2)
cin>>a[i]>>a[i+1];
int num=Religions(n,m,a);
cout<<num<<endl;
return 0;}

int Religions(int n,int m,int* record)
{int count=0;
int b[50000];
for(int j=0;j<n;j++)
b[j]=1;
for(j=0;j<2*m;j+=2)
if(b[record[j]-1]&&b[record[j+1]-1])
{count++;
b[record[j]-1]=0;
b[record[j+1]-1]=0;
}
else
{b[record[j]-1]=0;
b[record[j+1]-1]=0;
}
for(j=0;j<n;j++)
count+=b[j];
return count;
}

6 楼

#include <stdlib.h>
#include <stdio.h>

int Religions(int n,int m,int* record);
int main()
{
    int iRet;
    int record[]={1,2,1,3,1,4,1,5,1,6,1,7,1,8,1,9,1,10};
    iRet=Religions(10,9,record);
    printf("**%d**\n",iRet);
    return 0;
}


int Religions(int n,int m,int* record)
{
    int *ip;
    int i,iNum,iCount=0;
    ip=new int[n];
    for(i=0;i<n;i++)
        ip[i]=1;
    for(i=0;i<m;i++)
    {
        iNum=(record[i*2]>record[i*2+1]?record[i*2]:record[i*2+1]);
        ip[iNum-1]=0;
    }
    for(i=0;i<n;i++)
        if(ip[i])
            iCount++;
    return iCount;
}

7 楼

#include "stdio.h"
#include "stdlib.h"
#include "memory.h"

int Religions(int n,int m,int* record)
{
    int *p,*pEnd,*buff;
    register int t0,t1;
    int i,r,c=0;
    
    buff=new int[n+1];
    memset(buff,0,sizeof(int)*(n+1));

    for (pEnd=record+m*2,p=record;p<pEnd;p+=2)
    {
        t0=p[0];    t1=p[1];

        r= ( buff[t0] | buff[t1]);
        if (r)
            buff[t0]=buff[t1]=r;
        else
            buff[t0]=buff[t1]=++c;
    }
    
    for (i=1;i<=n;i++)
        if (buff[i]==0)
            c++;
    
    delete[] buff;
    return c;
}

8 楼


#include<stdio.h>

int Religions(int n,int m,int* record)
{
    int count,i,j,k;
    count = n-m;
    for(i=0;i<2*m;i+=2)
    {
        for(j=0;j<i-1;j++)
            for(k=0;k<i;k++)
                if((record[i]==record[j])&&(record[i+1]==record[k]))
                    count+=1;
    }
    return count;
}

void main(void)
{
    int n=10,m=4;
int record[]={2,3,4,5,4,8,5,8};
    int res;
    res=Religions(n,m,record);
    printf("%d",res);
}

9 楼

不好意思 把测试部分的代码也一起发上来了......实在不好意思.....

10 楼


int Religions(int n, int m, int* record)
{
    int i, j;
    int count = 0;
    int flag;
    int countCheck = m;
    
    if (n>=50000) return 0;
    if (m<0 || m>n*(n-1)/2 || m>=500000) return 0;
        
    for (i=1; i<=n; i++)
    {
        flag = 0;
        for (j=0; j<2*m; j++)
        {
            if (i == record[j]) flag = 1;
        }
        if (flag == 0) count++;
    }
    printf("count = %d\n", count);
    
    for (i=0; i<m-1; i++)
    {
        flag = 0;
        for (j=2*(i+1); j<2*m; j++)
        {
            if (record[i*2] == record[j] || record[i*2+1] == record[j])
            {
                flag = 1;
    printf("flag = %d, i= %d, j = %d\n", flag, i, j);
                break;
            }
        }
        if (flag == 1) countCheck--;
    }
    printf("countCheck = %d\n", countCheck);
    
    count += countCheck;
    
    return count;
}

我来回复

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