链接:传送门
题意:给出3 × 3的方块,其中任意2 × 2的方块和左上角2 × 2的和相等,还给出9个格子中的4个——a,b,c,d ,在1~n中选择一些数(可重复)填入剩下5个格子中,问有多少种填法
思路:设5个 ?分别为x1,x2,x3,x4,x5 ,最后合并整理可以求得两个式子:
- x4 - x2 = a - b + c - d
- x5 - x1 = a + b - c - d
先遍历x4 然后二分 x2 ,O(2nlog(n))的复杂度,理论上是没问题的
/*************************************************************************
> File Name: test1.cpp
> Author: WArobot
> Blog: http://www.cnblogs.com/WArobot/
> Created Time: 2017年04月17日 星期一 19时53分46秒
************************************************************************/
#include<bits/stdc++.h>
using namespace std;
int n,a,b,c,d;
int x1,x2,x4,x5;
int s1,s2;
int flag[100010];
int main(){
for(int i=0;i<100010;i++) flag[i] = i+1;
while(scanf("%d%d%d%d%d",&n,&a,&b,&c,&d)!=EOF){
int cnt1 = 0 , cnt2 = 0;
s1 = a-b+c-d; s2 = a+b-c-d;
for(x4=1;x4<=n;x4++){
if( binary_search(flag,flag+n,x4-s1) )
cnt1++;
}
for(x5=1;x5<=n;x5++){
if( binary_search(flag,flag+n,x5-s2) )
cnt2++;
}
printf("cnt1 = %d , cnt2 = %d
",cnt1,cnt2);
int t = min(cnt1,cnt2);
long long ans = t;
ans *= n;
cout<<ans<<endl;
}
return 0;
}
这样就完了?这样就结束了?还有更好的方法吗?当然有......
对于x4 - x2 = s1,有必要算x2吗?很显然没必要,只需要判断x2在符合的区间内就ok了,O(2n)还二分?被嘲讽为草履虫了......
/*************************************************************************
> File Name: d.cpp
> Author: WArobot
> Blog: http://www.cnblogs.com/WArobot/
> Created Time: 2017年04月17日 星期一 23时55分05秒
************************************************************************/
#include<bits/stdc++.h>
using namespace std;
int n,a,b,c,d,s1,s2,x4,x5;
int main(){
while(scanf("%d%d%d%d%d",&n,&a,&b,&c,&d)!=EOF){
s1 = a-b+c-d; s2 = a+b-c-d;
int cnt1 = 0 , cnt2 = 0;
// x4 - x2 = s1
for(x4=1;x4<=n;x4++)
if(x4-s1>=1 && x4-s1<=n) cnt1++;
// x5 - x1 = s2
for(x5=1;x5<=n;x5++)
if(x5-s2>=1 && x5-s2<=n) cnt2++;
long long ans = min(cnt1,cnt2);
ans *= n;
cout<<ans<<endl;
}
return 0;
}