SRM 449 div1 (practice)

250pt:

   暴力枚举所有的可能的情况就好了,求面积的时候我是用梯形的面积减去两个三角形的面积。。

550pt:
题意:给你一个蜂窝形状的特殊图形,有一些格子已经被占据了,问你将剩下的格子用1*2的砖块尽可能的铺满的总方案数,见下图。
SRM 449 div1 (practice) 
SRM 449 div1 (practice) 


此题想了半天,隐约感觉可以dp,但是无从D起,,,膜拜了下rng_58的超短代码(大部分人选择dfs转移),但是rng_58将图转换成网格后巧妙的使用逐格递推的方法,代码超短,简直就是高端洋气上档次啊,好想又好写,这种题我以前都是dfs写转移的,要,b半天才能写出来。。

 #include <cstdio>

#include <vector>

#include <cstring>

#include <cstdlib>

#include <algorithm>

using namespace std;

class HexagonalBattlefield{

    public :

int countArrangements(vector <int> X, vector <int> Y, int N) ;

};

int g[250][250];

long long  dp[2][1<<15];

const int mod =  2000000011;

void Add(long long &x,int y)

{

    x += y;

    if(x >= mod) x -= mod;

}

int dx[] = {1,0,-1,0,1,-1};

int dy[] = {0,1,0,-1,1,-1};

vector<pair<int,int> > p;

int HexagonalBattlefield::countArrangements(vector <int> X, vector <int> Y, int N)

{

    N --;

    for(int i = -N; i <= N; i++) {

        for(int j = -N; j <= N; j++) if(abs(i-j)  <= N ){//ddddd

    //    puts("ddd");

            int t = 0;

            for(int k = 0; k < X.size(); k++) {

                if(i == X[k] && j == Y[k]) {t=1;break;}

            }

            if(!t) p.push_back(make_pair(i,j));

        }

    }

  //  puts("dddd");

    int m = p.size();

    for(int i = 0; i < m; i++) {

        int x = p[i].first , y = p[i].second;

        for(int j = 0; j < 6; j++) {

            int tx = x + dx[j];

            int ty = y + dy[j];

            for(int k = 0; k < m; k++) if(tx == p[k].first && ty == p[k].second) {

                g[i][k] = true;

            }

        }   

    }

  //  printf("m=%d\n",m);

   // puts("debug"); 

    int cur = 0, nxt = 1;

    dp[cur][0] = 1;

    for(int i = 0; i < m; i++) {

      // printf("i=%d\n",i);

        memset(dp[nxt],0,sizeof(dp[nxt]));

        for(int j = 0; j < (1<<15); j++) if(dp[cur][j]){

            if(j&1) {Add(dp[nxt][j>>1] , dp[cur][j]); continue;}

            for(int k = 1; k <= 15; k++) if(i+k < m && g[i][i+k] && !( j&(1<<k) ) ) {

                int mask = ( j | (1 << k) )>> 1; 

                Add(dp[nxt][mask] , dp[cur][j]);

            }

        }

        std::swap(cur,nxt);

    }

    return dp[cur][0];

}





你可能感兴趣的:(div)