JZOJ 3807. 【NOIP2014模拟8.25】地砖铺设
Description
在游戲廳大賺了一筆的Randy 終于贏到了他想要的家具。乘此機會,他想把自己的房間好好整理一
下。
在百貨公司,可以買到各種各樣正方形的地磚,為了美觀起見,Randy 不希望同樣顏色的正方形地
磚相鄰。所以他找到了Tio 來幫忙解決這件事情。
Tio 很快解決了這個任務。然而,出于某種強迫癥,她希望在地上按照長寬劃分成網格后,逐行逐
列每一塊的顏色組成的序列的字典序最小。她希望你幫忙驗證一下她的方案。
Input
第一行,包含兩個整數N 和M,表示房間的長和寬。
Output
N 行,每行M 列,表示地磚鋪設的方案,需要這個方案是字典序最小的合法方案。(可以認為,輸出的方案去掉回車后形成的字符串字典序最小)
Sample Input
4 3
Sample Output
AAA
AAA
AAA
BCB
Data Constraint
? 對于分值為40 的子任務1,保證 N,M<=5
? 對于分值為60 的子任務2,保證 N,M<=100。
Solution
這道題看似簡單,事實上打起來十分麻煩——
這個方法是比較簡單的,逐一逐一地填。
如果填到一個正方形,則在它的右上角記錄它的邊長
對于一個點,從它的左邊、右邊和上邊算出它的最優字母,設為 k
如果這個點左邊的點有標記邊長,且也為 k ,那么當前的點擴展為之前的正方形
同時將 之前的邊長+1 賦到當前點上
如果不是,那么就直接填 k<script type="math/tex" id="MathJax-Element-5">k</script> ,邊長賦為 1 。
這樣不斷操作,就成功填完啦!!
Code
#include<cstdio> #include<cstring> using namespace std; const int N=101,way[3][2]={{0,1},{-1,0},{0,-1}}; int n,m,l=1,r; int f[N][N],g[N][N]; bool bz[5]; int main() {scanf("%d%d",&n,&m);while(true){if(++r>m) l++,r=1;if(l>n) break;if(f[l][r]) continue;int k=1;memset(bz,false,sizeof(bz));for(int i=0;i<3;i++){int x=l+way[i][0],y=r+way[i][1];if(!g[x][y] || i!=2) bz[f[x][y]]=true;}while(bz[k]) k++;if(f[l][r-1]==k && g[l][r-1]) {if(l+g[l][r-1]>n){k++;while(bz[k]) k++;f[l][r]=k;g[l][r]=1;continue;}g[l][r]=g[l][r-1]+1;for(int i=1;i<=g[l][r];i++) f[l+i-1][r]=k;for(int i=1;i<g[l][r];i++) f[l+g[l][r]-1][r-g[l][r]+i]=k;}else{f[l][r]=k;g[l][r]=1;}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++) printf("%c",f[i][j]+'A'-1);printf("\n");}return 0; }總結
以上是生活随笔為你收集整理的JZOJ 3807. 【NOIP2014模拟8.25】地砖铺设的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JZOJ 3808. 【NOIP2014
- 下一篇: JZOJ 3809. 【NOIP2014