2012 TCO Algorithm Championship Round - Division I, Level Two PeriodicTiling 题解

2012 TCO Algorithm Championship Round - Division I, Level Two PeriodicTiling 题解

首先考虑所有块完全一样这个条件。

假设按照向量\(\{v_1,v_2,v_3...\}\)平移整个平面和原来的完全重合。

取这组向量的两个基\(A,B\)

则所有的区域可以看作:

.    .    .    .
    .    .    .    .
    	.    .    .    .
    	    .    .    .    .

类似这样。

然后割补一下,可以发现答案恰好就是\(A,B\)的叉积。

然后只需要枚举平移向量就行了。

时间复杂度\(O(N^6)\)

code:

#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
//inline int read(){
//    int x=0;
//    char ch=getchar();
//    while(ch<'0'||ch>'9'){
//        ch=getchar();
//    }
//    while(ch>='0'&&ch<='9'){
//        x=(x<<1)+(x<<3)+(ch^48);
//        ch=getchar();
//    }
//    return x;
//}
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
vector<string> maze;
int n,m;
bool out(int x,int y){
	return !(x<3*n&&x>=0&&y<3*m&&y>=0);
}
char tmp[200][200];
bool check(int xa,int ya,int xb,int yb){
	rep(i,3*n) rep(j,3*m) tmp[i][j]='*';
	rep(i,n) rep(j,m) tmp[i+n][j+m]=maze[i][j];
	rep(i,3*n) rep(j,3*m){
		if(!out(i+xa,j+ya)){
			if(tmp[i][j]=='*') tmp[i][j]=tmp[i+xa][j+ya];
			else if(tmp[i+xa][j+ya]=='*') tmp[i+xa][j+ya]=tmp[i][j];
			else if(tmp[i+xa][j+ya]!=tmp[i][j]) return false;
		}
		if(!out(i+xb,j+yb)){
			if(tmp[i][j]=='*') tmp[i][j]=tmp[i+xb][j+yb];
			else if(tmp[i+xb][j+yb]=='*') tmp[i+xb][j+yb]=tmp[i][j];
			else if(tmp[i+xb][j+yb]!=tmp[i][j]) return false;
		}
		if(!out(i-xa,j-ya)){
			if(tmp[i][j]=='*') tmp[i][j]=tmp[i-xa][j-ya];
			else if(tmp[i-xa][j-ya]=='*') tmp[i-xa][j-ya]=tmp[i][j];
			else if(tmp[i-xa][j-ya]!=tmp[i][j]) return false;
		}
		if(!out(i-xb,j-yb)){
			if(tmp[i][j]=='*') tmp[i][j]=tmp[i-xb][j-yb];
			else if(tmp[i-xb][j-yb]=='*') tmp[i-xb][j-yb]=tmp[i][j];
			else if(tmp[i-xb][j-yb]!=tmp[i][j]) return false;
		}
	}
	return true;
}
class PeriodicTiling{
	public:
		int minBlock(vector<string> tmp){
			maze=tmp;
			n=maze.size();
			m=maze[0].length();
			int ans=INF;
			rb(xa,-n,n){
				rb(ya,0,m){
					rb(xb,-n,xa){
						rb(yb,0,m){
							if(abs(xa*yb-xb*ya)&&abs(xa*yb-xb*ya)<ans&&check(xa,ya,xb,yb)){
								check_min(ans,abs(xa*yb-xb*ya));
							}
						}
					}
				}
			}
			return ans;
		}
}solver;
posted @ 2021-08-07 18:12  WWW~~~  阅读(40)  评论(0编辑  收藏  举报