生活随笔
收集整理的這篇文章主要介紹了
[蓝桥杯][算法训练VIP]暗恋(二维树状数组)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述
同在一個高中,他卻不敢去找她,雖然在別人看 來,那是再簡單不過的事。暗戀,是他唯一能做的事。他只能在每天課間操的時候,望望她的位置,看看她傾心的動作,就夠了。操場上的彩磚啊,你們的位置,就是他們能夠站立的地方,他倆的關系就像磚與磚之間一樣固定,無法動搖。還記得當初鋪磚的工人,將整個操場按正方形鋪磚(整個操場可視為R行C列的矩陣,矩陣的每個元素為一塊正方形磚塊),正方形磚塊有兩種,一種為藍色,另一種為紅色。我們定義他和她之間的“愛情指標”為最大純色正方形的面積,請你寫一個程 序求出“愛情指標”。
數據規模和約定
R,C< =200;
輸入
第一行兩個正整數R和C。
接下來R行C列描述整個操場,紅色磚塊用1來表示,藍色磚塊用0來表示。
輸出
一個數,表示他和她之間的“愛情指標”。
樣例輸入
5 8
0 0 0 1 1 1 0 1
1 1 0 1 1 1 1 1
0 1 1 1 1 1 0 1
1 0 1 1 1 1 1 0
1 1 1 0 1 1 0 1
樣例輸出
9
思路:雖然數據量不大,但是純純的暴力也不行。我們可以枚舉一下正方形的邊長,看是否符合定義。但是枚舉了邊長,如何計算正方形的面積呢?難道要再循環嗎?這樣有事O(n*n)的時間復雜度。肯定承擔不起,因為我們要采用二維樹狀數組這種數據結構來求一下二維前綴和,這樣時間復雜度就降下來了。二維樹狀數組可以自行百度。
代碼如下:
#include<bits/stdc++.h>
#define ll long long
using namespace std
;const int maxx
=2e2+10;
int a
[maxx
][maxx
];
int c
[maxx
][maxx
];
int n
,m
;inline int lowbit(int x
){return x
&-x
;}
inline void update(int y
,int x
,int v
)
{while(y
<maxx
){int tx
=x
;while(tx
<maxx
) {c
[y
][tx
]+=v
;tx
+=lowbit(tx
);}y
+=lowbit(y
);}
}
inline int query(int x
,int y
)
{int sum
=0;while(x
){int ty
=y
;while(ty
){sum
+=c
[x
][ty
];ty
-=lowbit(ty
);}x
-=lowbit(x
);}return sum
;
}
inline int check(int &l
,int flag
)
{int x
,y
,sum
,len
;for(int i
=1;i
<=n
;i
++){for(int j
=1;j
<=m
;j
++){if(a
[i
][j
]&&flag
){while(1){x
=i
+l
;y
=j
+l
;if(x
<=n
&&y
<=m
) sum
=query(x
,y
)-query(x
,j
-1)-query(i
-1,y
)+query(i
-1,j
-1);else break;if(sum
==(l
+1)*(l
+1)) l
++;else break;}}else if(!a
[i
][j
]&&!flag
){while(1){x
=i
+l
;y
=j
+l
;if(x
<=n
&&y
<=m
) sum
=query(x
,y
)-query(x
,j
-1)-query(i
-1,y
)+query(i
-1,j
-1);else break;if(sum
==0) l
++;else break;}}}}
}
int main()
{scanf("%d%d",&n
,&m
);for(int i
=1;i
<=n
;i
++)for(int j
=1;j
<=m
;j
++) scanf("%d",&a
[i
][j
]);for(int i
=1;i
<=n
;i
++)for(int j
=1;j
<=m
;j
++) update(i
,j
,a
[i
][j
]);int len
=1;int ans1
=check(len
,1);int ans2
=check(len
,0);cout
<<len
*len
<<endl
;return 0;
}
努力加油a啊,(o)/~
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的[蓝桥杯][算法训练VIP]暗恋(二维树状数组)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。