牛客IOI周赛16-普及组-解题报告

本文精选三道数学算法竞赛题目,包括求导数的高阶导数计算、猜数游戏中最优策略的寻找以及答题卡对称图案的计数问题。通过深入解析,提供高效算法解决方案,涵盖阶乘计算、贪心算法及递推公式应用。

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

问题A-求导

牛牛今天题目描述学习了求导,对函数 f(x) 求导记作 f(x)'

已知  (x^n)′=n×x^n−1,同理可得 (x^n−1)′=(n−1)×x^n−2

其次 (a×x^n)′=a×(x^n)′,其中 a 是个常数。

求 x^n 求 n - 1 次导后 x 前的系数。( 比如求 2 次导时,有 f(x)''=(f(x)')'。)

输入描述:

给出一个数 n

输出描述:

输出求 x^n 求 n - 1 次导后 x 前的系数。(答案对 109+710^9+7109+7 取余)

输入

5

输出

120

备注:

对于 %50 的数据满足 n≤15

对于 %100 的数据满足 n≤10^5

题解:

求x^n的n-1次导为:n*x^(n-1)+(n-1)*x^(n-2).....1*x^0

x前的系数为n!

所以只需要求n!就行了

#include <bits/stdc++.h>
#define ll long long
const int Mod=1e9+7;
using namespace std;
ll n;
ll fac(ll x)
{
	ll res=1;
	for(int i=1;i<=n;i++)res=res*i%Mod;
	return res;
}
int main()
{
	scanf("%lld",&n);
	printf("%lld\n",fac(n));
}

问题B:猜数

纸上写了 n 个数字,牛牛在之前改动了几个数字,他忘了他具体改了些数字了。

但是他记得动之前这些数字的和是 ≥m 的,求他最少改动几个数字。

注意:这些数字在改之前和改之后均在 0 ~ 9 之间,且为整数。

输入描述:

第一行给出 n,m

第二行给出 n 个 0 ~ 9 的整数

输出描述:

输出最少改动了几个数字。(保证答案 ≤n\le n≤n)

示例1

输入

2 3
1 1

输出

1

备注:

对于 50%  数据有 n≤20

对于 100%  数据有 n≤10^6

题解:

贪心

首先把每一位数求和。

如果大于等于 k 那么就是没有改变,答案为 0。

如果小于 k,那肯定是从 0→9 开始改变,并且每次把这个数贪心地变成 9。

#include <bits/stdc++.h>
using namespace std;
int n,m;
int a[1000005];
int main()
{
    cin>>n>>m;
    int sum=0,ans=0;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        sum+=a[i];
    }
    sort(a+1,a+1+n);
    int i=0;
    while(sum<m)
    {
        i++;
        int t=a[i];
        a[i]=a[i]+(m-sum);
        if(a[i]>9)
        {
            sum+=(9-t);
            ans++;
        }
        else
        {
            ans++;
            break;
        }
    }
    cout<<ans<<endl;
}

问题C:答题卡

牛牛即将要参加考试,他学会了填答题卡。

可惜他竖着的答题卡填成了横着的 : (

好奇的他想知道对于 n 道题,每道题 n 个选项的答题卡 ( n * n 的矩阵 ),满足横答题卡和竖答题卡图形一致的方案数有多少种。

注:每道题只能选择一个选项,即 n * n 的矩阵中只能涂黑 n 个空。求横竖对称的方案数。

输入描述:

第一行给出 n。

输出描述:

输出方案数,答案对 10^9+7 取模

示例1

输入

3

输出

4

说明

 

备注:

对于 50%的数据有 n≤10

对于 100% 的数据有 n≤10^5

题解:

递推

考虑第一道题填的位置:

1. 如果填第一个空

则第一行和第一列均不可再填,则只需要右下的 (n-1)*(n-1) 的矩阵对称即可。

2. 如果不填第一个空

若填在 (1,x) 根据对称 (x,1) 也要填上,且第 1 行,第 1 列,第 x 行和第 x 列不能再填。

所以只需要让其余部分拼在一起构成 (n-2)*(n-2) 的矩阵对称即可。

设 n 的答案为 f(n) 不难写出递推式 f(n)=f(n-1)+(n-1)*f(n-2)

代码:

#include <bits/stdc++.h>
const int Mod=1e9+7;
using namespace std;
long long f[100005],n;
int main()
{
	scanf("%lld",&n);
	f[2]=2;
	f[3]=4;
	for(int i=4;i<=n;i++) f[i]=(f[i-1]+(i-1)*f[i-2])%Mod;
	printf("%lld\n",f[n]%Mod);
	return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值