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;
}