C. Fractal Detectortime limit per test
4 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Little Vasya likes painting fractals very much.
He does it like this. First the boy cuts out a 2 × 2-cell square out of squared paper. Then he paints some cells black. The boy calls the cut out square a fractal pattern.
Then he takes a clean square sheet of paper and paints a fractal by the following algorithm:
- He divides the sheet into four identical squares. A part of them is painted black according to the fractal pattern.
- Each square that remained white, is split into 4 lesser white squares, some of them are painted according to the fractal pattern. Each square that remained black, is split into 4 lesser black squares.
In each of the following steps step 2 repeats. To draw a fractal, the boy can make an arbitrary positive number of steps of the algorithm. But he need to make at least two steps. In other words step 2 of the algorithm must
be done at least once. The resulting picture (the square with painted cells) will be a fractal. The figure below shows drawing a fractal (here boy made three steps of the algorithm).
One evening Vasya got very tired, so he didn't paint the fractal, he just took a sheet of paper, painted a n × m-cell field. Then Vasya paint some
cells black.
Now he wonders, how many squares are on the field, such that there is a fractal, which can be obtained as described above, and which is equal to that square. Square is considered equal to some fractal if they consist of the same amount of elementary not divided
cells and for each elementary cell of the square corresponding elementary cell of the fractal have the same color.
Input
The first line contains two space-separated integers n, m (2 ≤ n, m ≤ 500) —
the number of rows and columns of the field, correspondingly.
Next n lines contain m characters each — the description
of the field, painted by Vasya. Character "." represents a white cell, character "*"
represents a black cell.
It is guaranteed that the field description doesn't contain other characters than "." and "*".
Output
On a single line print a single integer — the number of squares on the field, such that these squares contain a drawn fractal, which can be obtained as described above.
Sample test(s)input
6 11......*.****.*.*....**.***....*.*..***.*.....*.*.....**......*.*..
output
3
input
4 4..**..**........
output
0
Note
The answer for the first sample is shown on the picture below. Fractals are outlined by red, blue and green squares.
The answer for the second sample is 0. There is no fractal, equal to the given picture.
題目:http://codeforces.com/contest/228/problem/C
題意:這題題意表示我理解能力弱了??題目就是描述一種分型,將一個正方形平分成4分,任何選幾個塗成黑色,然後不斷的進行同樣的步驟,每次塗色方案與第一次相同,全是黑色的就不用塗了。。。。
分析:對這種類型不大熟悉,並不能一下子看出是狀態壓縮DP,不過猜得出來是DP,假設f[ i ][ j ][ t ][mask]表示(i,j)這個格子為左上方,長度為2^t的正方形的分型情況,也就是那幾個格子是黑色的,然後通過枚舉長度,就可以轉移了,具體還是比較簡單的。。。。
PS:這題想了好久沒思路,稍微瞄了一眼題解,想到了思路,然後就開始敲了,敲完後就悲劇了,不斷的wa。。。通過看資料,發現好像我理解錯了,重新看了幾遍題目都不知道哪錯了= =,後來不得以看別人代碼,才發現第二段沒仔細看,並不是只有圖上的那種情況是分型。。。。感覺重新敲,最後還由於長度限制小了wa了一次 T_T,能不能再弱點
代碼:
#include<cstdio>#include<iostream>using namespace std;const int mm=555;int f[mm][mm][11];int i,j,k,l,n,m,ans;char c;int check(int x,int y,int l){ if(x+l>=n||y+l>=m)return -1; int d[4]={f[x][y][k-1],f[x][y+l][k-1],f[x+l][y][k-1],f[x+l][y+l][k-1]}; int i,ret,s; for(i=0;i<4;++i) if(d[i]<0)return -1; for(i=0;i<4;++i) if(d[i]!=15)break; if(i==4)return 15; s=d[i]; for(ret=i=0;i<4;++i) if(d[i]!=15) { if(d[i]!=s)return -1; } else ret|=1<<i; if(l!=1&&s!=ret)return -1; return ret;}int main(){ while(~scanf("%d%d",&n,&m)) { for(i=0;i<n;++i) for(j=0;j<m;++j) { scanf(" %c",&c); f[i][j][0]=(c=='*')?15:0; } ans=0; for(k=1;(l=(1<<k))<=n&&l<=m;++k) for(i=0;i<n;++i) for(j=0;j<m;++j) ans+=(f[i][j][k]=check(i,j,l>>1))>-1&&k>1; printf("%d\n",ans); } return 0;}