Codeforces 675B Restoring Painting

链接:传送门
题意:给出3 × 3的方块,其中任意2 × 2的方块和左上角2 × 2的和相等,还给出9个格子中的4个——a,b,c,d ,在1~n中选择一些数(可重复)填入剩下5个格子中,问有多少种填法

思路:设5个 ?分别为x1,x2,x3,x4,x5 ,最后合并整理可以求得两个式子:

  1. x4 - x2 = a - b + c - d
  2. 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\n",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;
}
posted @ 2017-04-18 00:06  ojnQ  阅读(118)  评论(0编辑  收藏  举报