Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- const int COUNT = 20;
- const int N = 55;
- struct xorshift32 {
- unsigned x,y,z,w;
- xorshift32(): x(123456789), y(2378257), z(7777777), w(85715718) {}
- xorshift32(unsigned seed): x(123456789), y(2378257), z(7777777), w(seed) {}
- unsigned next() {
- unsigned t=x^(x<<11);
- x=y;y=z;z=w;
- return w=w^(w>>19)^t^(t>>8);
- }
- unsigned next(unsigned n) {
- return next()%n;
- }
- int next(int a, int b) {
- return a+next(b-a+1);
- }
- } rng;
- const char SHAPE[COUNT][4][4] = {
- {
- { 1, 0, 0, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 1, 0, 0, 0 },
- { 1, 0, 0, 0 },
- { 1, 0, 0, 0 },
- { 1, 0, 0, 0 }
- },
- {
- { 1, 1, 1, 1 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 1, 1, 0, 0 },
- { 1, 1, 0, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 1, 0, 0, 0 },
- { 1, 1, 0, 0 },
- { 1, 0, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 1, 1, 1, 0 },
- { 0, 1, 0, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 0, 1, 0, 0 },
- { 1, 1, 0, 0 },
- { 0, 1, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 0, 1, 0, 0 },
- { 1, 1, 1, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 1, 1, 0, 0 },
- { 1, 0, 0, 0 },
- { 1, 0, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 1, 1, 1, 0 },
- { 0, 0, 1, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 0, 1, 0, 0 },
- { 0, 1, 0, 0 },
- { 1, 1, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 1, 0, 0, 0 },
- { 1, 1, 1, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 1, 1, 0, 0 },
- { 0, 1, 0, 0 },
- { 0, 1, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 0, 0, 1, 0 },
- { 1, 1, 1, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 1, 0, 0, 0 },
- { 1, 0, 0, 0 },
- { 1, 1, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 1, 1, 1, 0 },
- { 1, 0, 0, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 1, 0, 0, 0 },
- { 1, 1, 0, 0 },
- { 0, 1, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 0, 1, 1, 0 },
- { 1, 1, 0, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 1, 1, 0, 0 },
- { 0, 1, 1, 0 },
- { 0, 0, 0, 0 },
- { 0, 0, 0, 0 }
- },
- {
- { 0, 1, 0, 0 },
- { 1, 1, 0, 0 },
- { 1, 0, 0, 0 },
- { 0, 0, 0, 0 }
- }
- };
- const int TYPE[COUNT] = {
- 0,
- 1,
- 1,
- 2,
- 3,
- 3,
- 3,
- 3,
- 4,
- 4,
- 4,
- 4,
- 5,
- 5,
- 5,
- 5,
- 6,
- 6,
- 7,
- 7
- };
- const int ROTATION[COUNT] = {
- 0,
- 0,
- 1,
- 0,
- 0,
- 1,
- 2,
- 3,
- 0,
- 1,
- 2,
- 3,
- 0,
- 1,
- 2,
- 3,
- 0,
- 1,
- 0,
- 1
- };
- const pair < int, int > ANCHOR[COUNT] = {
- make_pair(0,0),
- make_pair(0,0),
- make_pair(0,3),
- make_pair(0,0),
- make_pair(0,0),
- make_pair(0,2),
- make_pair(2,1),
- make_pair(1,0),
- make_pair(0,0),
- make_pair(0,2),
- make_pair(2,1),
- make_pair(1,0),
- make_pair(0,0),
- make_pair(0,2),
- make_pair(2,1),
- make_pair(1,0),
- make_pair(0,0),
- make_pair(0,2),
- make_pair(0,0),
- make_pair(0,1)
- };
- const pair < int, int > DIRECTIONS[4] = {
- make_pair(1,0),
- make_pair(-1,0),
- make_pair(0,1),
- make_pair(0,-1)
- };
- int tests,current_case;
- int n,m;
- char a[N][N];
- bool used[N][N];
- vector < pair < int, int > > places[COUNT];
- bool vis[N][N];
- int ans,shapes_count;
- int perm[N];
- int saved_ans,saved_shapes_count;
- vector < pair < int, int > > saved_places[COUNT];
- bool can(int idx, int r, int c) {
- if(SHAPE[idx][0][0]==1 && r==1 && c==1) return false;
- int i,j;
- for(i=0;i<4;i++) {
- for(j=0;j<4;j++) {
- if(SHAPE[idx][i][j]==1) {
- if(r+i>n || c+j>m) return false;
- if(used[r+i][c+j]) return false;
- }
- }
- }
- return true;
- }
- void place(int idx, int r, int c) {
- int i,j;
- for(i=0;i<4;i++) {
- for(j=0;j<4;j++) {
- if(SHAPE[idx][i][j]==1) {
- used[r+i][c+j]=true;
- }
- }
- }
- places[idx].push_back(make_pair(r,c));
- ans+=(idx==0 ? 1 : 6);
- ++shapes_count;
- }
- void unplace(int idx, int r, int c) { //Assumes the last placed of that type was the current one
- int i,j;
- for(i=0;i<4;i++) {
- for(j=0;j<4;j++) {
- if(SHAPE[idx][i][j]==1) {
- used[r+i][c+j]=false;
- }
- }
- }
- places[idx].pop_back();
- ans-=(idx==0 ? 1 : 6);
- --shapes_count;
- }
- void dfs(int r, int c) {
- vis[r][c]=true;
- if(used[r][c]) return;
- int i,p,t;
- for(i=0;i<4;i++) {
- p=r+DIRECTIONS[i].first;
- t=c+DIRECTIONS[i].second;
- if(p>=1 && p<=n && t>=1 && t<=m) if(!vis[p][t] && a[p][t]=='.') {
- dfs(p,t);
- }
- }
- }
- bool check() {
- int i,j,z,t;
- for(i=1;i<=n;i++) {
- for(j=1;j<=m;j++) {
- vis[i][j]=false;
- }
- }
- dfs(1,1);
- for(i=0;i<COUNT;i++) {
- for(j=0;j<(int)(places[i].size());j++) {
- bool has=false;
- for(z=0;z<4;z++) {
- for(t=0;t<4;t++) {
- if(SHAPE[i][z][t]==1) if(vis[z+places[i][j].first][t+places[i][j].second]) {
- has=true;
- }
- }
- }
- if(has==false) return false;
- }
- }
- return true;
- }
- void save_ans() {
- saved_ans=ans;
- saved_shapes_count=shapes_count;
- for(int i=0;i<COUNT;i++) {
- saved_places[i]=places[i];
- }
- }
- void print_used() {
- int i,j;
- for(i=1;i<=n;i++) {
- for(j=1;j<=m;j++) {
- if(used[i][j]) printf("1");
- else printf("0");
- }
- printf("\n");
- }
- printf("---\n");
- }
- int main() {
- int i,j,z,it;
- for(i=0;i<COUNT-1;i++) {
- perm[i]=i+1;
- }
- scanf("%d", &tests);
- for(current_case=1;current_case<=tests;current_case++) {
- scanf("%d %d", &n, &m);
- for(i=1;i<=n;i++) {
- scanf("%s", a[i]+1);
- for(j=1;j<=m;j++) {
- if(a[i][j]=='.') used[i][j]=false;
- else used[i][j]=true;
- }
- }
- saved_ans=0;
- for(it=1;it<=5;it++) {
- for(i=0;i<COUNT-1;i++) {
- swap(perm[i],perm[rng.next(COUNT-1)]);
- }
- for(i=1;i<=n;i++) {
- for(j=1;j<=m;j++) {
- if(a[i][j]=='.') used[i][j]=false;
- else used[i][j]=true;
- }
- }
- ans=0;
- shapes_count=0;
- for(i=0;i<COUNT;i++) {
- places[i].clear();
- }
- for(i=n;i>=1;i--) {
- for(j=m;j>=1;j--) {
- for(z=0;z<COUNT-1;z++) if(can(perm[z],i,j)) {
- place(perm[z],i,j);
- if(!check()) unplace(perm[z],i,j);
- }
- }
- }
- for(i=n;i>=1;i--) {
- for(j=m;j>=1;j--) {
- if(can(0,i,j)) {
- place(0,i,j);
- if(!check()) unplace(0,i,j);
- }
- }
- }
- if(ans>saved_ans) {
- save_ans();
- }
- }
- printf("%d %d\n", saved_shapes_count, saved_ans);
- for(i=0;i<COUNT;i++) {
- for(j=0;j<(int)(saved_places[i].size());j++) {
- printf("%d %d %d %d\n", saved_places[i][j].first+ANCHOR[i].first, saved_places[i][j].second+ANCHOR[i].second, TYPE[i], ROTATION[i]);
- }
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement