We use cookies to ensure you have the best browsing experience on our website. Please read our cookie policy for more information about how we use cookies.
#include<cstdio>#include<cstring>#define MOD 1000000007// Solution uses memoization of a brute-force solving of all permutations.// Number of rows and columns.intn,m;// Character representation of the grid.charg[50][5];// Valid configurations for row i (up to 2**5 of them).intgood[50][1<<5];// Number of valid configurations in row i.intszg[50];// Array of N bitmasks containing 111 for each M.intblock[50];// Number of solutions for a given row and bitmask.intmemo[50][1<<15];// The next bitmask, given a particular bitmask.intmemo2[1<<15];// Get the next bitmask with queen attack vectors accounted for.intspread(intmask){// Solutions been found before, use it.if(memo2[mask]!=-1)returnmemo2[mask];intnmask=0;// For each squarefor(inti=0;i<m;i++){// If a left-angling attack vector exists and we're not at the left edge,// extend it into the left-diagonal square.if(mask&1<<3*i&&i>0){nmask|=1<<3*i-3;}// If a vertical attack vector exists, extend it into the square below.if(mask&1<<3*i+1){nmask|=1<<3*i+1;}// If a right-angling attack vector exists and we're not at the right edge,// extend it into the right-diagonal square.if(mask&1<<3*i+2&&i+1<m){nmask|=1<<3*i+5;}}returnmemo2[mask]=nmask;}// Solve for row x, with a mask for squares that are blocked by earlier queens.intsolve(intx,intmask){// We've reached the end of a solution, so return.if(x==n)return1;// Adjust the mask for squares that are already blocked.mask&=~block[x];// If we've already solved this, return the result.if(memo[x][mask]!=-1)returnmemo[x][mask];// If not, count solutions.intret=0;// For each configuration of this rowfor(inti=0;i<szg[x];i++){// If we haven't tried all configurations yetif(!(good[x][i]&mask)){// Try the next row, with rows blocked by queens masked out.ret+=solve(x+1,spread(good[x][i]|mask));// Don't let the number get too big.if(ret>=MOD)ret-=MOD;}}returnmemo[x][mask]=ret;}intsolve(){// For each row in Nfor(inti=0;i<n;i++){block[i]=0;intcmask=0;for(intj=0;j<m;j++){if(g[i][j]=='#'){// Create bitmask for #, like 01001cmask|=1<<j;// Create bitmask with 111111111111111 (for M==5)block[i]|=7<<3*j;}}szg[i]=0;// For each 2**M permutations of queens on this rowfor(intj=0;j<1<<m;j++){// If the queen is not on a #if((j&cmask)==0){boolvalid=true;// For each column in Mfor(intk=0;k<m;k++){// If a queen is in that column, and another queen is on the same row// before another #, then that position isn't valid.if(j&1<<k){for(intkk=k+1;kk<m&&g[i][kk]!='#';kk++){if(j&1<<kk){valid=false;}}}}if(!valid)continue;// If this is a valid configuration of queens for this row, create a// bitmask with 111 where a queen is. Add it to the good matrix at row i// and increment the size of that row (szg).intsp=0;for(intk=0;k<m;k++){if(j&1<<k){sp|=7<<3*k;}}good[i][szg[i]]=sp;szg[i]++;}}}// Initialize memoization tables to -1 for each entry.memset(memo,255,sizeofmemo);memset(memo2,255,sizeofmemo2);// Solve recursively.returnsolve(0,0);}intmain(){intruns;scanf("%d",&runs);while(runs--){scanf("%d%d",&n,&m);// Initialize board.for(inti=0;i<n;i++)scanf("%s",g[i]);intret=solve();ret=(ret-1+MOD)%MOD;printf("%d\n",ret);}return0;}
Cookie support is required to access HackerRank
Seems like cookies are disabled on this browser, please enable them to open this website
Queens on Board
You are viewing a single comment's thread. Return to all comments →
C++ Solution