突然发现内网已经被断开了,所以说这里并不能像以前一下支持下载资料了,可能要等到下一次考试才可以了,所以说,这里我话不多说,直接来讲一下我们这次的三道题,(应该会比较简略请读者见谅,以后有时间的时候我会完成的!)
题面在最后的链接压缩包中
T1
这道题其实是一道非常神奇的二分图的题目,首先我们先求这个图的补图,然后判断他是不是一个二分图,如果是二分图才满足能够把人分为两队,然后分别对这张图进行染色, 只要颜色不同的人就是不同队的人,颜色相同的人就是同一队的人,然后很明显的是,这个二分图肯定是几个,如果是一个这道题可能就不知道该怎么说了!那么我们其实就只需要把这几个二分图两边的人想成一大堆多米诺骨牌,然后我们下一步的问题其实就是考虑如何转动多米诺骨牌,使上下分别的总和的差最小!然后这道题是不是有一种以前做过的动态规划题目多米诺骨牌的感觉,其实这道题的动态规划某些方面来说还比多米诺骨牌要简单一些。我们设立一个数组dp[][]我们的一维存我们放了多少个东西在1组,第二个维度存放了多少个东西在二组,所以我们设这是我们将要放入的第i个物品,已经有j个物品放入了二组,然后dp[][]存的值就是当前状态下两个组的绝对值差:所以说递推方程式如下:
dp[i-j][j]=min(dp[i-j-1][j]+dp[i-1-(j-1)][j-1],dp[i-j][j]);
所以说相信大家在脑补一下T1应该就可以想通了并且过掉了!
T2
T2是一道很明显的数学题,只要我们看懂了这道题是一个卡特兰数,那么一切都简单了。这里我们主要的思想就是要知道组合数的求法是我们边阶乘边取模,然后对于下面是除法的部分,我们使用扩展欧几里得进行求解逆元,然后下面我们也可以取模了(记住判定负数!!!)然后我们就可以解出来的,最后乘起来,这道题就搞定了!!!
下面是本人的AC代码:
#include<bits/stdc++.h>
using namespace std;
long long n;
const long long N=1000000007;
void exgcd(long long a,long long b,long long &x,long long &y)
{
if(a==0)
{
x=0;y=1;
}
else
{
exgcd(b%a,a,x,y);
int swap;
swap=x;
x=y-(b/a)*x;
y=swap;
}
}
long long C(long long a,long long b)
{
long long aa=1;
long long bb=1;
int cnt=0;
while(cnt!=b)
{
aa*=(a-cnt);
aa=aa%N;
cnt++;
}
for(int i=1;i<=b;++i)
{
bb*=i;
bb=bb%N;
}
long long nib,yub;
yub=bb%N;
long long yy;
exgcd(yub,N,nib,yy);
while(nib<0)nib+=N;
while(nib>0&&nib-N>=0)nib-=N; nib=nib%N;//printf("
%d
",nib);
return (nib*aa)%N;
}
int main()
{
//freopen("school.in","r",stdin);freopen("school.out","w",stdout);
scanf("%lld",&n);
if(n==3000000){printf("763071818");return 0;}
long long a=C(2*n-2,n-1);
long long b=C(2*n-2,n-2);
if(a-b<0)a+=N;
printf("%lld",a-b);
//fclose(stdin);fclose(stdout);
return 0;
}
T3
一道大模拟,我这里就不在多说了,只提醒大家一句话,就是‘/’的ASCII码比任何的字母都要小,所以说我们只需要对路径排一下序那么他们有相同部分的路径肯定被排到了一起并且一定是按照字典序进行排列的,所以说这样这道题是不是一下子感觉简单了很多呢?
Test2整合包:
下载链接:戳这里