題目描述:(二分圖最大匹配問題)若兩個正整數的和為素數,則這兩個正整數稱之為「素數伴侶」,如2和5、6和13,它們能應用於通訊加密。現在密碼學會請你設計乙個程式,從已有的n(n為偶數)個正整數中挑選出若干對組成「素數伴侶」,挑選方案多種多樣,例如有4個正整數:2,5,6,13,如果將5和6分為一組中只能得到一組「素數伴侶」,而將2和5、6和13編組將得到兩組「素數伴侶」,能組成「素數伴侶」最多的方案稱為「最佳方案」,當然密碼學會希望你尋找出「最佳方案」。
輸入描述:有乙個正偶數n(n≤100),表示待挑選的自然數的個數。後面給出n個具體的數字,範圍為[2,30000]。4
2 5 6 13
輸出描述:求得的「最佳方案」組成「素數伴侶」的對數。2
二分圖最大匹配問題:1.問題引出通過數代人的努力,你終於趕上了剩男剩女的大潮,假設你是一位光榮的新世紀媒人,在你的手上有n個剩男,m個剩女,每個人都可能對多名異性有好感。
如果一對男女互有好感,那麼你就可以把這一對撮合在一起,你擁有的大概就是下面這樣一張關係圖,每一條連線都表示互有好感。並且現在的要求是,盡可能撮合更多對新人。
2. 嘗試進行解決
find(x); //表示當前對x號男生進行尋偶
line[i][j]; //表示 i 號男生和 j 號女生是否有好感
girl[j]; //表示 j 號女生的配偶編號
used[j]; //在當前挑選過程中,j號女生被used[j]號男生宣布了主權
line_num++; //x號男生牽手成功
偽**:
used 為全域性變數,因為發生遞迴時候要共用
girl 為全域性變數,因為發生遞迴時候要共用
line 為全域性變數,因為發生遞迴時候要共用
for(int i=0; i下面給出前兩步的詳細執行過程:
順序遍歷每個男生,假設當前是 1 號男生
①順序遍歷所有女生嘗試給1號男生找女朋友( find(1) ),(此時1號男生沒有對任何乙個女生宣布主權( used= ))
a)發現1號女生沒有被宣布主權
b)發現和一號女生互有好感 line(1,1)==true
c)宣布自己對1號女生的主權 used[1]=true
d)發現1號女生無主( girl[1]==-1 )get,將1號女生配偶編號改變( girl[1]=1 ),對數加1(藍線)line_num++; find(1)返回true;
e)返回false
注意到:女生沒有被其他人宣布主權,互有好感&&女生無主 才可以get,line_num++
②順序遍歷所有女生嘗試給2號男生找女朋友 ( find(2) ),(此時每個男生都沒有對任何乙個女生宣布主權( used= ))
a)發現1號女生沒有被人宣布主權
b)發現2號男生和1號女生互有好感 line(2,1)==true
c)宣布2號男生對1號女生的主權 used[1]=true
d)但是1號女生有主,無法get( 無法令girl[1]=2 ),,此時girl[1]=1,呼叫find(1),看是否可以為1號男生找到乙個新的女生
如果 find(1)為true,那麼get,令girl[1]=2,find(2)返回ture
e)返回false
此時讓一號女生原來的男朋友即1號男生去尋找新的女朋友即( find(1) )此時used中已經存在了乙個被宣布主權的( used[1]==2 )(注意此時1號男生的find是巢狀在2號男生的find內部(發生了遞迴),並且2號男生和1號男生公用乙個used,這個used是目前只有2號男生有乙個宣布主權的物件,這就保證了,1號男生不會選擇當前已經被2號男生宣布了主權的1號女生)
我們來觀察find(1),
a) 1號男1號女生已經被宣布主權 used[1]==true
,那麼 1號男生要跳過1號女生去對2號女生進行嘗試
b)發現和2號女生互有好感 line(1,2)==true
c)宣布1號男生對2號女生的主權 used[2]=true
d)2號女生無主( girl[2]==-1 )get,將1號女生配偶編號改變( girl[2]=1 ),對數加1(藍線)line_num++; find(1)返回true;
e)返回false
做題思路:1. 首先明確只有乙個偶數和乙個奇數相加才會產生乙個素數。因此我們可以將輸入的偶數都當做男生,將輸入的奇數都當做 女生2. 是否有好感的判定就是用乙個 isprime函式即可,這個多種方法,很好搞定
3. 建立好感二維矩陣,然後就完事兒了(千萬不要建立好感矩陣,直接判斷兩個數是否有好感,否則會記憶體超限)
ac**:#include#include#include#includeusing namespace std;
vectoreven(1); //存放輸入的偶數
vectorodd(1); //存放輸入的奇數
int used[100];
int girl[100];
bool isprime(int num);
int isfind(int x);
int main()
else
} int line_num=0;
memset(girl,0,sizeof(girl));
for(int i=1; i
cout<
odd.clear();
odd.push_back(1);
even.clear();
even.push_back(1); }
return 0;
} bool isprime(int num)
if( num%6!=1&&num%6!=5 )
int temp=sqrt(num);
for(int i=5; i<=temp; i+=6)
} return true;
}int isfind(int x)
} }return 0;
}
華為OJ 素數伴侶
素數伴侶 題目描述 若兩個正整數的和為素數,則這兩個正整數稱之為 素數伴侶 如 2和5 6和13,它們能應用於通訊加密。現在密碼學會請你設計乙個程式,從已有的n n為偶數 個正整數中挑選出若干對組成 素數伴侶 挑選方案多種多樣,例如有 4個正整數 2,5,6,13,如果將5和 6分為一組中只能得到一...
素數伴侶 匈牙利演算法
對於0和1來說,它們既不是素數也不是合數。任何乙個大於1的正整數n,可以且唯一表示成有限個素數的乘積。素數 在乙個大於1的自然數中,除了1和此整數自身以外,不能被其他自然數整除的數。比1大,但不是素數則稱之為合數。匈牙利演算法 增廣路徑的理解 理解一 在二分圖的匹配中,如果一條路徑的首尾是非匹配點,...
28 素數伴侶(匈牙利演算法)
題目描述 題目描述 若兩個正整數的和為素數,則這兩個正整數稱之為 素數伴侶 如2和5 6和13,它們能應用於通訊加密。現在密碼學會請你設計乙個程式,從已有的n n為偶數 個正整數中挑選出若干對組成 素數伴侶 挑選方案多種多樣,例如有4個正整數 2,5,6,13,如果將5和6分為一組中只能得到一組 素...