比赛链接: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,会加深理解。

京公网安备 11010502036488号