topcoder 乱作系列1 srm500 srm501 srm502

SRM 500 250pts

答案一定是被选次数最多的人被选的概率,模拟第一次后的结果,考虑剩下的个数。以后每次剩下的都是用n%当前的个数。

#include <bits/stdc++.h>
using namespace std;
#define N 510
int val[N];
class MafiaGame
{
    public:
    double probabilityToLose(int n,vector<int>a)
    {
        int mx=0;double ret=1;
        for(int i=0;i<a.size();i++)
            val[a[i]]++,mx=max(mx,val[a[i]]);
        int tot=n-a.size(),cnt=0;
        for(int i=0;i<n;i++)
            if(val[i]<=mx-1)
                tot-=mx-1-val[i],val[i]=mx-1;
            else cnt++;
        if(tot>0)cnt+=tot;          
        if(mx==0)cnt=n;
        while(cnt!=1)
        {
            if(n%cnt==0)return 0;
            ret=ret*(n%cnt)/cnt;
            cnt=n%cnt;
        }
        return ret;
    }
}tmp;

SRM 500 500pts

搜搜搜!!!! 扒了题解的代码,感觉还是很妙的,避免精度误差。
由于给出的坐标都是整数,所以边界上递归下去的并不多。

#include <bits/stdc++.h>
using namespace std;
#define N 510
int val[N];
class FractalPicture
{
    double cal(int deep,int x1,int x2,int y1,int y2)
    {
        x1=max(x1,-27);x2=min(x2,27);
        y1=max(y1,0);y2=min(y2,81);
        if(x1>x2||y1>y2)return 0;
        if(x1==-27&&x2==27&&y1==0&&y2==81)
            return deep*54+27;
        if(deep==1)
        {
            if(x1>0||x2<0)return 0;
            return y2-y1;
        }
        double ret=0;
        if(x1<=0&&x2>=0&&y1<=54)
            ret=min(y2,54)-y1;
        return ret+1.0/3*(
            cal(deep-1,x1*3,x2*3,(y1-54)*3,(y2-54)*3)+
            cal(deep-1,(y1-54)*3,(y2-54)*3,x1*3,x2*3)+
            cal(deep-1,(y1-54)*3,(y2-54)*3,-x2*3,-x1*3));
    }
    public:
    double getLength(int x1,int y1,int x2,int y2)
    {
  return cal(500,x1,x2,y1,y2);}
}tmp;

SRM 500 1000pts

1,2,4,8,6,3,9的个数不固定,手动枚举2,4,8,9的个数可以确定1,3的个数。
/*
注 意 枚 举 顺 序!!!!!!!!!!!!!!!!!!!!!!
妈蛋枚举的时候顺序不对搞出负数本机和tc测的不一样调了半天我会乱说?
(手动注释)*/
对于每一数字单独计算个数,设i出现的次数为 ai ,那么考虑某个 ai 出现在指定的一位,那么它对答案的贡献为:
(n1)!ai!a1!a2!...a10!(ai1)!i
预处理一个 ten[i]=10i+10i1+....+1 就可以计算该情况下每个数字的贡献了。

#include <bits/stdc++.h>
using namespace std;
#define mod 500500573
#define ll long long
#define N 2600
ll ten[N],jc[N],njc[N];
int cnt[21];
ll qpow(ll x,ll y)
{
    ll ret=1;
    while(y)
    {
        if(y&1)ret=ret*x%mod;
        x=x*x%mod;y>>=1;
    }
    return ret;
}
class ProductAndSum
{
    public:
    int getSum(int p2,int p3,int p5,int p7,int sum)
    {
        ll ret=0;
        ten[0]=1;jc[0]=njc[0]=1;

        for(int i=1;i<=sum;i++)jc[i]=jc[i-1]*i%mod;
        njc[sum]=qpow(jc[sum],mod-2);
        for(int i=sum-1;i>=1;i--)njc[i]=njc[i+1]*(ll)(i+1)%mod; 

        for(int i=1;i<=sum;i++)ten[i]=(ten[i-1]*10ll)%mod;
        for(int i=1;i<=sum;i++)ten[i]=(ten[i]+ten[i-1])%mod;

        for(cnt[2]=0;cnt[2]<=p2;cnt[2]++)
            for(cnt[4]=0;cnt[4]*2+cnt[2]<=p2;cnt[4]++)
                for(cnt[8]=0;cnt[8]*3+cnt[4]*2+cnt[2]<=p2;cnt[8]++)
                {
                    cnt[6]=p2-cnt[2]-cnt[8]*3-cnt[<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值