比赛链接:https://ac.nowcoder.com/acm/contest/5389
A:https://ac.nowcoder.com/acm/contest/5389/A
题意:求图片说明进行n-1次求导后的图片说明 前面的系数 。
思路:第一次求导时,前面系数是n,第二次是n(n-1),那么n-1次后就是(n-0)*(n-1)(n-2)……(n-(n-2))恰好是n!。至此代码也就写出来了。

//author CN.TTDragon
#include<bits/stdc++.h>
typedef long long ll;
const ll mod=1e9+7;//这里模数要用上
const ll maxn=1e5+7;
const double pi=acos(-1);
using namespace std;
int main()
{
    ll n;
    cin>>n;
    ll ans=1;
    for(int i=1;i<=n;i++)
    {
        ans*=i;    
        ans%=mod;//模运算
    } 
    cout<<ans<<endl;
     return 0;
}

B:https://ac.nowcoder.com/acm/contest/5389/B
题意:给你n个数的同时给你另一个数m。给你的n个数只能是0-9。问你至少要改变几个数才能使得这n个数的和大于等于m。
思路:既然数组里面的数只有10种可能的值,不妨使用一下桶排序。再来想一下,同样的使总和大于等于m,那么肯定是让当前最小的数变成9所带来的收益最大。于是贪心的思路就来了。那就是从0开始,把所有数都变成9直到当前的和大于等于m。至此代码也就可以写出来了。细节看一下代码注释。

//author CN.TTDragon
#include<bits/stdc++.h>
typedef long long ll;
const ll mod=1e9+7;
const ll maxn=1e5+7;
const double pi=acos(-1);
using namespace std;
int main()
{
    int tong[10]={0};//桶排序
    int n,m;
    cin>>n>>m;
    int a;
    int tot=0;//当前的总和
    int ans=0;
    for(int i=0;i<n;i++)
    {
        cin>>a;
        tot+=a;
        tong[a]++;
    }
    m-=tot;//现在的m就是差值
    int i=0;
    while(true)//注意理解这个循环的目的,找tot<m<=tot+i
    {
        m-=tong[i]*(9-i);//先莽一些,把当前这个数字全变成9
        ans+=tong[i];//于此同时答案就要加上这次变成9的数字的个数
        if(m<=0)//如果此时的和已经大于等于m了,那就说明答案不会大于这个数。
        {
            m+=tong[i]*(9-i);//再次莽,又当它从来没有变过9。
            ans-=tong[i];//答案也要减去这个数
            break;//跳出循环
        }
        else
        {
            i++;//说明此时这些数根本不够,要把下一个数里面的部分或全部变成9.
        }
    }
    //这个i就是贪心下还能修改的最大的数字了
    if(m%(9-i)==0)//整除的话是等于
    {
        ans+=m/(9-i);    
    } 
    else//不能整除需要补个1
    {
        ans+=m/(9-i)+1;    
    }
    cout<<ans<<endl;
     return 0;
}

C:https://ac.nowcoder.com/acm/contest/5389/C
题意:给你一个数n,问你有多少种染色方法可以使染色后的n * n的矩阵是关于主对角线对称的。
矩阵的每一行只能有一列被染色,矩阵的每一列也只能有一行被染色。(吐槽一下:解释如何涂单选题答题卡怎么这么麻烦)
思路:由于是对称的,我们来想,假设我们涂的是第一行第一列,那么就会剩下一个(n-1) * (n-1)的矩阵没染色,那么如果我涂的不是第一行第一列,那么由于对称性,第x行第一列其实也就染上色了。于是,就剩下一个(n-2) * (n-2)的矩阵没染色。这个x有n-1种取法。于是状态转移方程也就写出来了dp[i]=dp[i-1]+(i-1)*dp[i-2]。然后我们直到当n=1,2,3时的方案数是1,2,4。你要是勤快点,自己画一画,n=4时,方案数是10。至此代码也就写出来了。

//author CN.TTDragon
#include<bits/stdc++.h>
typedef long long ll;
const ll mod=1e9+7;
const ll maxn=1e5+7;
const double pi=acos(-1);
using namespace std;
ll dp[maxn]={0,1,2,4};
int main()
{
    for(int i=4;i<=maxn;i++)
    {
        dp[i]=dp[i-1]+(i-1)*dp[i-2];
        dp[i]%=mod;//记得进行模运算
    }

    int n;
    cin>>n;
    cout<<dp[n]<<endl;
     return 0;
}

写在最后:
不会树学,D题直接傻了。这个C的状态转移方程还挺好想,想不出来可以用Excel模拟一下n=4,会加深理解。