問題:
在w*h的格仔上畫了n條垂直或者水平的寬度為1的直線。求出這些直線將格仔劃分為了多少個區域?
限制條件:
1<= w,h <= 1000000
1<= n <= 500
輸入:首先輸入w,h,n;然後輸入對應的x1,x2,y1,y2.輸出區域的個數。
輸入:
10 10 5
x1:1 1 4 9 10
x2:6 10 4 9 10
y1:4 8 1 1 6
y2:4 8 10 5 10
輸出:
6分析:
我們可以用乙個陣列表示所有的格仔,然後將格仔分為直線上的和不在直線上的,然後進行bfs搜尋。但是由於w,h很大,沒辦法開那麼大的陣列。所以我們要利用座標離散化得技巧。
如輸入樣例所示:
座標離散化的主要思想是:將前後沒有變化的行列消除後並不影響區域的個數
陣列裡只需要儲存有直線的行列和前後的行列就足夠了,這樣的話大小最多為6n*6n了。
然後在利用bfs搜尋即可。
現在我們來考慮個細節,如果我們原本是不相鄰的,可我們離散化後就變的相鄰了,怎麼辦?這樣的話,我們就要做偏移處理,
下來的**中for(int d=-1 ; d<=1 ; d++) 這個就是偏移處理,是為了防止這種情況的發生,為什麼呢?
下面舉個例子,5與8 如果沒有偏移處理那5對應的是1,8對應的是2,那這兩個是相鄰的,但他們並不相鄰,也就是x...x變成了xx,這是錯誤的,
那偏移後就是4,5,6,7,8,9; 5記錄的是2,8記錄的是5,那他們離散後表示的就沒有相鄰
**及其解析:
#include#define max 510view codeusing
namespace
std;
intn,w,h;
intx1[max],x2[max],y2[max];
inty1[max];
bool fld[max*6][max*6
];///
對x1和x2進行座標離散化,並返回離散化之後的寬度
///對x1,x2更新為離散後的x1,x2,y不變在x方向上縮小
int net[4][2]=,,,};
int compress( int *x1,int *x2,int
w) }
///離散化兩部曲
sort(xs.begin(),xs.end());///
排序 xs.erase(unique(xs.begin(),xs.end()),xs.end());///
去重
///轉化為新的x1,x2
for(int i=0 ; i)
return
xs.size( );
}void
so ( )
}///求區域的個數
int ans=0
;
for(int y=0 ; y)}}
}printf(
"%d\n
",ans);
}int
main( )
}
座標離散化
問題 在w h的格仔上畫了n條垂直或者水平的寬度為1的直線。求出這些直線將格仔劃分為了多少個區域?限制條件 1 w,h 1000000 1 n 500 輸入 首先輸入w,h,n 然後輸入對應的x1,x2,y1,y2.輸出區域的個數。輸入 10 10 5 x1 1 1 4 9 10 x2 6 10 4...
座標離散化
原理 從稀疏矩陣中把有效資料提出來,放在乙個新的座標系中 include include include include include include include const int inf 1e6 const int maxn 510 using namespace std int w,h,...
二維座標離散化
離散化的思想就是將分布大卻數量少 即稀疏 的資料進行集中化的處理,這樣可以有利於程式的空間與時間,能減少遍歷次數與空間儲存。然而雖然我會了思想今天問了翔神半天才知道怎麼實現。其實實現的方式與口述的角度還是有所不同。思想理解起來其實道理很簡單,如座標 3,2000 10005,31 10006,5 離...