2020CCPC秦皇岛 A,F,G(其他待补)

A Greeting from Qinhuangdao

题意

  • 在这里插入图片描述

  • 袋中有r个红球和b个蓝球,随机取两个,问取得两个红球的概率

解题思路

  • 求概率,用公式
  • 记s=r+b
    q = C r 2 C s 2 = r ∗ ( r − 1 ) 2 s ∗ ( s − 1 ) 2 q=\frac{ \quad\mathrm{C}_r^2\quad} {\quad\mathrm{C}_s^2\quad} =\frac{\frac{r*(r-1)}{2}}{\frac{s*(s-1)}{2}} q=Cs2Cr2=2s(s1)2r(r1)
  • 注意分子分母化简用gcd

代码

#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
	int t,x,y;
	scanf("%d",&t);
	for(int k=1;k<=t;k++)
	{
		scanf("%d%d",&x,&y);
		int sum=x+y;
		if(sum<2||x<2)
		{
			printf("Case #%d: 0/1\n",k);
			continue;
		}
		if(sum==x)
		{
			printf("Case #%d: 1/1\n",k);
			continue;
		}
		x=x*(x-1)/2;
		y=sum*(sum-1)/2;
		int tmp=__gcd(x,y);
		x/=tmp;y/=tmp;
		printf("Case #%d: %d/%d\n",k,x,y);
	}
	return 0;
} 

Friendly Group

题意

  • 在这里插入图片描述

  • 有n个人其中m对是好朋友,任意选人数参加聚会,聚会的快乐值=好朋友对数-总人数,求最大的聚会的快乐值

解题思路

  • 画图可知聚会的快乐值=所有 边数-点数>0的连通块 的 边数-点数 之和

代码

#include<stdio.h>
#include<algorithm>
using namespace std;
const int maxn=3e5+5;
int vis[maxn],fa[maxn],ans_v[maxn],ans_e[maxn];
int find(int x)
{
	if(x!=fa[x])fa[x]=find(fa[x]);
	return fa[x];
}
void join(int x,int y)
{
	int fx=find(x),fy=find(y);
	if(fx!=fy)
	{
		fa[fx]=fy;
		ans_v[fy]+=ans_v[fx];
		ans_e[fy]+=ans_e[fx]+1;
	}else ans_e[fy]++;
	return;
}
int main()
{
	int T;
	scanf("%d",&T);
	for(int I=1;I<=T;I++)
	{
		int n,m,x,y;
		scanf("%d%d",&n,&m);
		for(int i=0;i<=n;i++)
		{
			fa[i]=i;ans_v[i]=1;ans_e[i]=0;vis[i]=0;
		}
		for(int i=1;i<=m;i++)
		{
			scanf("%d%d",&x,&y);
			join(x,y);
		}
		int ans=0;
		for(int i=1;i<=n;i++)
		{
			int tmp=find(i);
			if(!vis[tmp])
			{
				if(ans_e[tmp]-ans_v[tmp]>0)
				ans+=ans_e[tmp]-ans_v[tmp];
				vis[tmp]=1;
			}
		}
		printf("Case #%d: %d\n",I,ans);
	}
	return 0;
}

Good Number

题意

  • 在这里插入图片描述

  • 若x可以整除 ⌊ x k   ⌋ \lfloor \sqrt[k]{x}\ \rfloor kx  则称x为好数,问1到n有多少个好数

解题思路

  • 数学,分类讨论
  • 令z= ⌊ n k   ⌋ \lfloor \sqrt[k]{n}\ \rfloor kn  
i范围 ⌊ x k   ⌋ \lfloor \sqrt[k]{x}\ \rfloor kx  
1 1 k 1^k 1k
2 1 k 1^k 1k +1 ~ 2 k 2^k 2k-11 2 k 2^k 2k
3 2 k 2^k 2k +1 ~ 3 k 3^k 3k-12 3 k 3^k 3k
……………………
i ( i − 1 ) k (i-1)^k (i1)k +1 ~ i k i^k ik-1i-1 i k i^k ik
……………………
z ( z − 1 ) k (z-1)^k (z1)k +1 ~ z k z^k zk-1z-1 z k z^k zk

根据上表可见第四列的数都是好数,共z个
分别统计2到z行中第二列的范围内的好数的个数为 i k − 1 − ( i − 1 ) k i − 1 \frac{i^k-1-(i-1)^k}{i-1} i1ik1(i1)k

代码

#include<stdio.h>
#include<math.h>
#include<algorithm>
using namespace std;
typedef long long ll;
ll power(int a,int b)
{
	int res=1;
	while(b) 
	{
		if(b&1)res=1ll*res*a;
		a=1ll*a*a;b>>=1;
	}
	return res;
}
int main()
{
	int t,n,k;
	scanf("%d",&t);
	for(int now=1;now<=t;now++)
	{
		scanf("%d%d",&n,&k);
		if(k==1)
		{
			printf("Case #%d: %d\n",now,n);
			continue;
		}
		int z=pow(n,1.0/k);
		ll ans=z,tmp=power(z,k);
		if(tmp+1<=n)ans+=n/z-tmp/z;
		for(int i=2;i<=z;i++)
			ans+=(power(i,k)-1-power(i-1,k))/(i-1);
		printf("Case #%d: %lld\n",now,ans);
	}
	return 0;
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值