2013年多校联合第一场

C题:数论题目,讨论n和k的大小关系,很明显n==k时输出1,n-k==1时是2,n<k时无结果为0,在n>k时推出公式2^(n-k)+(n-k-1)*2^(n-k-2),然后通过整数快速幂就可以了

对于1 <= k < n,我们可以等效为n个点排成一列,并取出其中的连续k个点。下面分两种
情况考虑: 
第一种情况,被选出的不包含端点,那么有(n – k − 1)种情况完成上述操作,剩下未被圈的点
之间还有(n – k − 2)个位置,可以在每个位置断开,所以共2^(n−k−2) ∗ (n−k−1)种方法。 
第二种情况,即被选出的包含端点,那么有2种情况,并且剩余共(n – k − 1)个位置,所以共
2 ∗ 2^(n – k − 1)种方法。 
总计2 ∗ 2^(n – k − 1) + 2^(n – k − 2) ∗ (n – k − 1)  =2^(n-k)+(n-k-1)*2^(n-k-2)

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define mod 1000000007
using namespace std;


long long a,b;
long long power(long long a,long long b)
{
    long long ans=1;
    while(b)
    {
        if(b&1)
        {
            ans=ans*a%mod;
            b--;
        }
        else
        {
            b=b/2;
            a=a*a%mod;
        }
    }
    return ans;
}

int main()
{
    //freopen("C:\\Users\\Administrator\\Desktop\\in.txt" , "r" , stdin);
    int t;
    int n,k;
    cin>>t;
    while(t--)
    {
        cin>>n>>k;
        if(n==k)cout<<1<<endl;
        else if(n-k==1)cout<<2<<endl;
        else if(n<k)cout<<0<<endl;
        else cout<<(power(2,n-k)+(power(2,n-k-2)*(n-k-1))%mod)%mod<<endl;
    }
    return 0;
}

H题:图论

# include<cstdio>
# include<cstring>
# include<algorithm>
using namespace std;

# define N 100005
int head[N],num,tag,maxd;

struct node
{
    int u,v,next;
}e[N*2];

inline void add(int u,int v)
{
    e[num].u=u;
    e[num].v=v;
    e[num].next=head[u];
    head[u]=num++;
}

void addedge(int u,int v)
{
    add(u,v);
    add(v,u);
}

void dfs(int f,int u,int d)
{
    int i,v;
    if(d>maxd)
    {
        maxd=d;
        tag=u;
    }
    for(i=head[u];i!=-1;i=e[i].next)
    {
        v=e[i].v;
        if(v==f)
            continue;
        dfs(u,v,d+1);
    }
}

void init()
{
    num=0;
    memset(head,-1,sizeof(head));
    maxd=0,tag=1;
}

int main()
{
    int i,n,m,k,end,T,u,v;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        init();
        for(i=1;i<n;i++)
        {
            scanf("%d%d",&u,&v);
            addedge(u,v);
        }
        dfs(0,1,0);
        maxd=0;
        dfs(0,tag,0);
        for(i=1;i<=m;i++)
        {
            scanf("%d",&k);
            if(k<=maxd+1)
                printf("%d\n",k-1);
            else
                printf("%d\n",maxd+2*(k-maxd-1));
        }
    }
    return 0;
}


I题:大数加法,直接暴力枚举

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=1000020;
char s[maxn];
int ans[maxn];
int len;

int add()
{
    ans[len]+=1;
    int sum=0;
    for(int i=len;i>=0;--i)
    {
        if(ans[i]>=10)
        {
            ans[i]%=10;
            ans[i-1]++;
        }
        sum+=ans[i];
    }
    return sum;
}
int main()
{
    int x,y,sum;
    int i,t,m;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",s);
        len=strlen(s);
        for(i=1; i<=len; i++)
            ans[i]=s[i-1]-'0';
        ans[0]=0;
        while(1)
        {
            if(add()%10==0) break;
        }

        if(ans[0]) printf("%d",ans[0]);
        for(int j=1; j<=len; j++)
            printf("%d",ans[j]);
        printf("\n");
    }
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值