分数统计

分数统计

【PrayerOJ-4950】

【题目描述】

在统计完朋友情况之后,小明又对大家的毕业学校产生兴趣,但是他觉得单纯的统计人数是一件非常无聊的事情,于是他设计了一个算法,同一所学校毕业的学生,第1个将获得1 分,第2个获得2分,第3个获得4分…,第i个将获得2i-1分,总分就是这所小学的得分,小明想知道得分最高的学校有多少分。

【输入】

输入文件score.in的第一行有两个整数n和m,n表示总人数,m表示已知的同校关系数量。

接下来n行,每行有2个以空格隔开的整数a和b,表示a和b是来自同一所学校,a和b均为1到n之间的整数。不会给出重复的信息。

【输出】

输出文件 score.out 只有一行,为所有学校中的最高得分。最后得分可能会很大,你只需要输出后 100 位即可,不足 100 位的请直接输出。

【样例输入】

5 3

1 2

3 4

1 3

【样例输出】

15

【样例说明】

1、2、3、4来自同一所学校,该所学校所得的分数为1+2+4+8=15

【数据规模】

60%的数据,1 <= n <= 10

80%的数据,1 <= n <= 70

100%的数据,1 <= n <= 10000,1 <= m <= 100000

【代码】

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>

#define RI        register int
#define re(i,a,b) for(RI i=a; i<=b; i++)
#define ms(i,a)   memset(a,i,sizeof(a))

using namespace std;

typedef long long LL;

int const N=10005;

int n,m;
int f[N],s[N];

struct bignum {
    int l,x[105];
    void init(int v) {
        l=0;
        ms(0,x);
        while(v) {
            x[++l]=v%10;
            v/=10;
        }
    }
};

int find(int x) {
    return x==f[x] ? x:f[x]=find(f[x]);
}

bignum cf(bignum a) {
    bignum c;
    c.init(0);
    re(i,1,a.l) {
        c.x[i]=a.x[i]*2+c.x[i-1]/10;
        c.x[i-1]%=10;
    }
    c.l=a.l;
    while(c.x[c.l]>9) {
        c.l++;
        c.x[c.l]=c.x[c.l-1]/10;
        c.x[c.l-1]%=10;
    }
    if(c.l>100) c.l=100;
    return c;
}

int main() {
  scanf("%d%d",&n,&m);
  re(i,1,n) f[i]=i,s[i]=1;
  int num=1;
  while(m--) {
      int x,y;
      scanf("%d%d",&x,&y);
      int fx=find(x);
      int fy=find(y);
      if(fx!=fy) {
          f[fx]=fy;
          s[fy]+=s[fx];
          num=max(num,s[fy]);
      }
  }
  bignum ans;
  ans.init(1);
  re(i,1,num) ans=cf(ans);
  ans.x[1]--;
  for(int i=ans.l; i>=1; i--) printf("%d",ans.x[i]);
  return 0;
}

 

转载于:https://www.cnblogs.com/ljnoit/articles/10699858.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值