2013----多校联合5

本文详细探讨了算法、编程技巧及其在不同领域的应用,包括但不限于大数据开发、前端开发、后端开发等。文章通过实例展示了如何解决实际问题,并提供了优化策略。无论是对于初学者还是经验丰富的开发者,都能从中获益。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1005:

若没有边权,则对点权从大到小排序即可。。

考虑边,将边权拆成两半加到它所关联的两个点的点权中即可。

。。因为当两个人分别选择不同的点时,这一权值将互相抵消。

智商是硬伤啊

#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
using namespace std;
double w[100001];
int main()
{
    //freopen("1005.in","r",stdin);
    int n,m,i,a,c,b;
    while(~scanf("%d%d",&n,&m))
    {
        memset(w,0,sizeof(w));
        for(i=1;i<=n;i++)scanf("%lf",&w[i]);
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            w[a]+=1.0*c/2;
            w[b]+=1.0*c/2;
        }
        double s;
        s=0;
        sort(w+1,w+n+1);
        for(i=n;i>=1;i-=2)
        {
            s+=w[i]-w[i-1];
        }
        printf("%.0lf\n",s);
    }
    return 0;
}



1006:

数组sum[i]:代表第i个数和其之前的数的和对m取余。

若sum[i]=sum[j],那么i和j之间的数肯定满足是m的倍数,则就可以去掉,问题转化成找最大的(j-i)使得sum[j]=sum[i];

在读入数据的时候对sum[i]=x进行标记,若之前标记过sum[j]=x,那么计算差值(j-i),取最大值。

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
#define maxn 100005
#define ll __int64
ll vis[maxn*2];
int main()
{
    //freopen("data.in","r",stdin);
    ll i,n,m;
    ll sum;
    ll a;
    while(scanf("%I64d%I64d",&n,&m)!=EOF)
    {
        sum=0;
        int ans=0;
        memset(vis,-1,sizeof(vis));
        vis[0]=0;
        int maxm=100000;
        for(i=1;i<=n;i++)
        {
            scanf("%I64d",&a);
            a=a%m;
            sum=sum+a;
            sum=sum%m;
            if(sum<0)
            {
                if(vis[sum+maxm]==-1)vis[sum+maxm]=i;
                else if(ans<i-vis[sum+maxm])ans=i-vis[sum+maxm];
                //continue;
            }
            if(sum<0)sum=sum+m;
            if(vis[sum]==-1)vis[sum]=i;
            else
            {
                if(ans<i-vis[sum])ans=i-vis[sum];
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}


1007:

对位的进制进行dp。

dp[i][j][k]:运行到第i个数,第j位为k(0或1)的概率。

lc[i][j]     :第i个数的第j位为多少(0或者1)

p[i]         :第i个数加入运算的概率。

若运算符为^

dp[i][j][0]=dp[i-1][j][0]*(1-p[i]);

dp[i][j][1]=dp[i-1][j][0]*(1-p[i]);//这两条是若此数为加入运算。

dp[i][j][0^lc[i][j]]+=dp[i-1][j][0]*p[i];

dp[i][j][1^lc[i][j]]+=dp[i-1][j][1]*p[i];//这两条是若此数加入了运算

#include<stdio.h>
#include<vector>
#include<string.h>
#include<iostream>
using namespace std;
int    lc[301][22];
int    fu[301];
double p[301];
double dp[301][301][30];
int n;
int main()
{
    int cas=1,i,t,a;
    char str[1001];
    while(scanf("%d%*c",&n)!=EOF)
    {
        memset(dp,0,sizeof(dp));
        memset(lc,0,sizeof(lc));
        for(i=0;i<=20;i++)p[i]=0;
        for(i=0;i<=n;i++)
        {
            scanf("%d",&a);
            int cs=1;
            while(a)
            {
                lc[i][cs]=a%2;
                a=a/2;
                cs++;
            }
        }
        getchar();
        gets(str);
        for(i=1;i<=n;i++)
        {
            if(str[i*2-2]=='^')fu[i]=1;
            else if(str[i*2-2]=='|')fu[i]=2;
            else if(str[i*2-2]=='&')fu[i]=3;
        }
        p[0]=1;
        double cp;
        for(t=1;t<=20;t++)
        {
            if(lc[0][t]==1)dp[0][t][1]=1;
            else dp[0][t][0]=1;
        }
        for(i=1;i<=n;i++)
        {
            scanf("%lf",&cp);
            p[i]=1-cp;
        }

        for(i=1;i<=n;i++)
        {
            for(t=1;t<=20;t++)
            {
                dp[i][t][0]=dp[i-1][t][0]*(1-p[i]);
                dp[i][t][1]=dp[i-1][t][1]*(1-p[i]);
                if(fu[i]==1)
                {
                    dp[i][t][0^lc[i][t]]+=dp[i-1][t][0]*p[i];
                    dp[i][t][1^lc[i][t]]+=dp[i-1][t][1]*p[i];
                }
                else if(fu[i]==2)
                {
                    dp[i][t][0|lc[i][t]]+=dp[i-1][t][0]*p[i];
                    dp[i][t][1|lc[i][t]]+=dp[i-1][t][1]*p[i];
                }
                else if(fu[i]==3)
                {
                    dp[i][t][0&lc[i][t]]+=dp[i-1][t][0]*p[i];
                    dp[i][t][1&lc[i][t]]+=dp[i-1][t][1]*p[i];
                }
            }
        }
        double ans;
        ans=0.0;
        for(t=1;t<=20;t++)
        {
            ans+=dp[n][t][1]*(1<<(t-1));
        }
        printf("Case %d:\n%.6lf\n",cas++,ans);
    }
    return 0;
}

1009:

给你一个数n,问你n能分成多少种数相加。

比如3=1+1+1,3=1+2,3=3

f[3]=3;

参见五边形定理.




#include<iostream>
#include<stdio.h>
using namespace std;
#define mo 1000000007
__int64 f[100001];
int main()
{
    int T,i,k,n;
    scanf("%d",&T);
    f[1]=1;
    f[0]=1;
    for(i=2;i<=100000;i++)
    {
        for(k=1;;k++)
        {
            int t1,t2;
            t1=i-k*(3*k+1)/2;
            t2=i-k*(3*k-1)/2;
            if(k%2==0)
            {
                if(t1>=0)f[i]-=f[t1];
                if(t2>=0)f[i]-=f[t2];
            }
            else
            {
                if(t1>=0)f[i]+=f[t1];
                if(t2>=0)f[i]+=f[t2];
            }
            if(t1<=0&&t2<=0)break;
            f[i]=f[i]%mo;
            if(f[i]<0)f[i]+=mo;
        }
    }
    while(T--)
    {
        scanf("%d",&n);
        printf("%I64d\n",f[n]);
    }
    return 0;
}



=======持续更新=======

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值