2021 12.2 模拟赛总结

作为高中开学后的第一次模拟赛,意义自然独特。

一共三道题,个人而言都是偏简单的(但是时间给的太短了。。顺道吐槽一下能不能多给点样例,这样手残就能发现了。。

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

这次模拟赛就当是一次经验的积累,以后要多注意细节问题,不要手残!!! 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值