作为高中开学后的第一次模拟赛,意义自然独特。
一共三道题,个人而言都是偏简单的(但是时间给的太短了。。顺道吐槽一下能不能多给点样例,这样手残就能发现了。。)
T1:给定一个多项式(ax + by)k,请求出多项式展开后xn ym项的系数。
共一行,包含 5 个整数,分别为 a , b , k , n , m ,每两个整数之间用一个空格隔开。输出共 1 行,包含一个整数,表示所求的系数,这个系数可能很大,输出对 10007 取模后的结果。
很显然跟杨辉三角有关系,但是我看后面两道题都是递推,式子很好推,就最后做的这道题,然后就忘记取模了(悲
首先需要建一下杨辉三角
for(int i=1 ; i<=k+1 ; i++){
f[i][1] = 1;
f[i][i] = 1; //先预处理第一列和最右侧一列的1
}
for(int i=3 ; i<=k+1 ; i++){ //2已经预处理完了,从3开始
for(int j=2 ; j<i ; j++){ //注意要从2开始
f[i][j] = (f[i-1][j-1]+f[i-1][j])%mod; //注意取模
}
}
然而,我们发现不仅仅有x和y,还有系数······这样只能过50%的测试点。
系数需要拿纸推一下,可以展开每一项,把ax和by看成一个整体,自己用稍微小一点的数据就会发现,最后答案要乘n次a,m次b。
直接最后乘上就行了,别忘了取模!
最终代码:
#include<bits/stdc++.h>
using namespace std;
const int mod = 10007;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch == '-') f=-1 ; ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-48 ; ch=getchar();}
return x*f;
}
int a,b,k,n,m;
int f[1100][1100];
int ans;
int main(){
freopen("factor.in","r",stdin);
freopen("factor.out","w",stdout);
a=read();b=read();k=read();n=read();m=read();
if(k==0){
printf("1\n");
return 0;
}
for(int i=1 ; i<=k+1 ; i++){
f[i][1] = 1;
f[i][i] = 1;
}
for(int i=3 ; i<=k+1 ; i++){
for(int j=2 ; j<i ; j++){
f[i][j] = (f[i-1][j-1]+f[i-1][j])%mod;
}
}
ans = f[k+1][k-n+1];
for(int i=1 ; i<=n ; i++) ans = (ans%mod) * (a%mod) % mod;
for(int i=1 ; i<=m ; i++) ans = (ans%mod) * (b%mod) % mod;
printf("%d",ans%mod);
return 0;
}
T2:汉诺塔由编号为 1 到 n 大小不同的圆盘和三根柱子 a,b,c 组成。开始时,这 n 个圆盘由大到小依次套在 a 柱 上,如图所示。要求把 a 柱上 n 个圆盘按下述规则移到 c 柱上:
(1) 一次只能移一个圆盘,它必须位于某个柱子的顶部;(2) 圆盘只能在三个柱上存放;(3) 任何时刻不允许大盘压小盘。将这 n 个盘子从 a 柱移动到 c 柱上,最少需要移动多少次?
一道经典的递推题目,考虑一个n,很容易发现可以从n-1推出,而且由于多了一个圆盘,在移动的时候次数需要乘二,最后别忘了要加1,就是最后一步挪到柱子上。
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch == '-') f=-1 ; ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-48 ; ch=getchar();}
return x*f;
}
long long f[100];
int main(){
freopen("hanoi.in","r",stdin);
freopen("hanoi.out","w",stdout);
int n;
n=read();
f[1] = 1;
f[2] = 3;
for(int i=3 ; i<=30 ; i++) f[i] = 2*f[i-1] + 1; //注意不要手残,考试时把i写成n了,直接挂了/(ㄒoㄒ)/~~
printf("%lld\n",f[n]);
return 0;
}
T3:
也是一道递推题。 该位置可以由前两个位置推出 (很容易想到吧)。
#include<bits/stdc++.h>
using namespace std;
inline int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch == '-') f=-1 ; ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-48 ; ch=getchar();}
return x*f;
}
long long f[100];
int main(){
freopen("domino.in","r",stdin);
freopen("domino.out","w",stdout);
int n;
n=read();
f[1] = 1;
f[2] = 2;
for(int i=3 ; i<=50 ; i++) f[i] = f[i-1]+f[i-2];
printf("%lld\n",f[n]);
return 0;
}
这次模拟赛就当是一次经验的积累,以后要多注意细节问题,不要手残!!!