问题描述:
今天CZY又找到了三个妹子,有着收藏爱好的他想要找三个地方将妹子们藏起来,将一片空地抽象成一个R行C列的表格,CZY要选出3个单元格。但要满足如下的两个条件:
(1)任意两个单元格都不在同一行。
(2)任意两个单元格都不在同一列。
选取格子存在一个花费,而这个花费是三个格子两两之间曼哈顿距离的和(如(x1,y1)和(x,y2)的曼哈顿距离为|x1-x2|+|y1-y2|)。狗狗想知道的是,花费在minT到maxT之间的方案数有多少。
答案模1000000007。所谓的两种不同方案是指:只要它选中的单元格有一个不同,就认为是不同的方案。
输入格式:
一行,4个整数,R、C、minT、maxT。3≤R,C≤4000, 1≤minT≤maxT≤20000。
对于30%的数据, 3 ≤ R, C ≤ 70。
输出格式:
一个整数,表示不同的选择方案数量模1000000007后的结果。
输入输出样例:
输入样例 |
3 3 1 20000 |
3 3 4 7 |
4 6 9 12 |
7 5 13 18 |
4000 4000 4000 14000 |
输出样例 |
6 |
0 |
264 |
1212 |
859690013 |
做法很简单,找规律即可。
大概做了一个小时,正常耗时。
代码实现:
1 #include<cstdio> 2 #include<iostream> 3 #define mod 1000000007 4 using namespace std; 5 long long n,m,l,r,ans; 6 long long a[8010],b[8010]; 7 int main(){ 8 freopen("excel.in","r",stdin); 9 freopen("excel.out","w",stdout); 10 cin>>n>>m>>l>>r; 11 a[4]=n-2;a[6]=n*2-6; 12 for(int i=8;i<=n*2-2;i+=2) a[i]=a[i-2]*2-a[i-4]-2; 13 b[4]=m-2;b[6]=m*2-6; 14 for(int i=8;i<=m*2-2;i+=2) b[i]=b[i-2]*2-b[i-4]-2; 15 for(int i=4;i<=n*2-2;i+=2) 16 for(int j=4;j<=m*2-2;j+=2) 17 if(i+j>=l&&i+j<=r) ans+=a[i]*b[j],ans%=mod; 18 cout<<ans*6%mod<<endl; 19 return 0; 20 }
本题我的方法应该不是正统的正解,正解应该是根据九宫格的特点推广。