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∗(s−1)2r∗(r−1) - 注意分子分母化简用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-1 | 1 | 2 k 2^k 2k |
3 | 2 k 2^k 2k +1 ~ 3 k 3^k 3k-1 | 2 | 3 k 3^k 3k |
…… | …… | …… | …… |
i | ( i − 1 ) k (i-1)^k (i−1)k +1 ~ i k i^k ik-1 | i-1 | i k i^k ik |
…… | …… | …… | …… |
z | ( z − 1 ) k (z-1)^k (z−1)k +1 ~ z k z^k zk-1 | z-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}
i−1ik−1−(i−1)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;
}