螺釘螺母的匹配問題
很早之前就看到一道關於螺釘螺母的acm題目的。最近又看了「分治法」的思想,於是強迫自己去把這個**寫出來!
題目如下:
給你一堆螺母和螺帽,每個螺母都有乙個相對應的螺帽,但是他們之間的對應關係已經打亂。你可以比較螺母和螺帽的大小關係,但是你無法比較螺母和螺母的大小關係,你也無法比較螺帽和螺帽的大小關係。設計乙個演算法,找出螺母和螺帽的對應關係。
當然,我肯定是衝著時間複雜度nlogn去的。否則就暴力解法了。
思路如下:螺母我就用nut表示,螺釘我就用bolt表示。方便區別,否則螺母螺釘的叫,都叫混了……
我是假設只有唯一乙個匹配的,即nut陣列與bolt一一對應。否則演算法還需要有更大的更改。
1.在nut陣列拿乙個,可以把bolt陣列分為比那個小的,比那個大的,還有乙個匹配的3個部分。
2.在bolt中小的那堆那乙個可以把nut分成比那個小的,比那個大的,還有乙個匹配的3個部分。
3.這樣可以發現,現在陣列產生兩對比配的螺母和螺釘和一隊小的螺釘和螺母,一隊大的螺釘和螺母。
如圖所示:
我令陣列內部的排列也是這樣。一次呼叫後前兩個是匹配的螺母和螺釘。後面給乙個座標,左邊是小的,右邊是較大的。
這樣我對較小的螺母和螺釘再呼叫乙個次函式,即又可以產生兩對匹配,和較小小和較大大的。呵呵!
說到這裡,可以發現這個跟快速排序的原理很相似。
先上幾個輔助函式:
//方便除錯使用。交換指定的兩個元素
void swap(int *a, int *b)
//列印指定陣列
void print(int *a)
cout
<
}
下面是正文:
//根據之前說的思想寫的。首先對上面的陣列進行分組,再對下面的陣列分組。分類函式
//n和b為兩個陣列
//left為左索引,right為右索引
void fix(int *n, int *b, int left, int
right)
while (i < j&&b[j] >tmp)
if (i
}b[i] =tmp;
swap(b[left], b[i]);
cout
<< "
n+b:
"<< endl; print(n); print(b); cout <
//一趟下來,i=j的tmp的位置。以tmp為界限,左右分別是小於和大於它的元素
tmp = b[left + 1
]; i = left + 1, j =right;
while (i
while (i < j&&n[j] >tmp)
if (i
}n[i] =tmp;
swap(n[left + 1
], n[i]);
cout
<< "
n+b:
"<< endl; print(n); print(b); cout <
fix(n, b, left + 2
, i);
fix(n, b, i + 1
, right);}}
最後遞迴呼叫兩遍fix函式。從left+2到i,因為已經有兩組匹配了,所有left+2,i是分界點。
另一組自然就是i+1到right了。
測試用例為:
int nut[9] = ;函式呼叫過程為:int bolt[9] = ;
fix(nut, bolt,
0, 8);
swap(a[l], a[l+count]); // a的左半部分分配count個元素
swap(b[mark],b[l+count]);// b的左半部分分出來count個元素
mark = l+count; // mark就是相同的匹配了,mark就是中軸
int i = l, j = r;
while (imark)
};
C 螺釘和螺母問題
做題時,遇到了這個問題,順手記錄一下。問題描述 假設我們有n個直徑各不相同的螺釘以及n個相應的螺母。我們一次只能比較一對螺釘和螺母,來判斷螺母是大於螺釘 小於螺釘還是正好適合螺釘。然而,我們不能拿兩個螺母作比較,也不能拿兩個螺釘作比較。我們的問題是要找到每一對匹配的螺釘和螺母。為該問題設計乙個演算法...
分治演算法求螺絲螺母匹配問題
有個大小不同的螺絲和與之匹配的n個螺母,你可以嘗試乙個螺絲和乙個螺母是否匹配,嘗試結果有三種 1 螺絲太大 2 匹配成功 3 螺母太大.請設計乙個分治演算法完成所有螺絲和螺母的匹配 邊界條件 當只有乙個螺絲和乙個螺母時,匹配螺絲和螺母。divide 在杯子集合中隨機選擇乙個螺絲x,將x與所有螺母進行...
正則 貪婪匹配 最大匹配 和最小匹配的問題。
貪婪匹配 最大匹配 和最小匹配的問題。在抓取鏈結位址時,使用以下正則時發現,當在鏈結標題 鏈結標題中含有html 時,不能抓取到位址。href s i 尚若換成以下方式 href s i 則不能抓取到你需要的鏈結資料,預設情況下,perl使用的是貪婪匹配模式,也就是盡可能多的匹配資料。如 下面的指令...