假設(shè)有一個數(shù)組a[N] N<=20
能不能從數(shù)組a中任選M個元素(M<=N),使得其和為K。佳縣網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)公司,佳縣網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為佳縣1000+提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)營銷網(wǎng)站建設(shè)要多少錢,請找那個售后服務(wù)好的佳縣做網(wǎng)站的公司定做!
解題思路:窮舉法
利用窮舉法,將所有的情況進(jìn)行運(yùn)算,直到找到該子數(shù)組為止。
我們利用二進(jìn)制來表示數(shù)組中的數(shù)據(jù)是否在子數(shù)組中,其中0表示不在,1表示在。
例如數(shù)組a為{21, 1, 35, 15, 32, 12, 5, 7},我們需要找到三個數(shù)之和為79。
則用二進(jìn)制進(jìn)行表示則為00110100(這里要注意的是,二進(jìn)制表示與數(shù)組的順序是反過來的,則00000001,表示的是a[0],而不是a[7])。
同時,我們對該二進(jìn)制數(shù)據(jù)進(jìn)行右移運(yùn)算,并與1進(jìn)行與運(yùn)算,當(dāng)結(jié)果為1的時候,我們將數(shù)據(jù)進(jìn)行相加,如果與K相等并且二進(jìn)制表示中的1的個數(shù)與M相等,則數(shù)組a中有M個元素其和為K。
針對于這個算法,我們需要利用到兩個for循環(huán),第一個for循環(huán)用來對各種情況進(jìn)行遍歷,第二個for循環(huán)用來對第一個循環(huán)中的情況進(jìn)行運(yùn)算,即:
for (int i = 0; i< (1<< N); i++) // i用于統(tǒng)計各種情況
{for (int j = 0; j< N; j++)
{……
}
}
對于第二個循環(huán)中,我們應(yīng)該如何去針對于第一個循環(huán)中的情況進(jìn)行運(yùn)算呢?
例如,數(shù)組a為{21, 1, 35, 15, 32, 12, 5, 7},我們需要找到三個數(shù)之和為79,而這中情況用二進(jìn)制進(jìn)行表示則為00110100
在第二個循環(huán)中,當(dāng)j=2時,該二進(jìn)制數(shù)進(jìn)行右移兩位,結(jié)果為00001101,我們再對它與1進(jìn)行與運(yùn)算,結(jié)果為1
所以,我們找到了我們需要的第一個數(shù),即為a[2],以此類推,我們就會找到剩下的兩個數(shù)
所以第二個循環(huán)的j表示的是右移的位數(shù),當(dāng)與1與運(yùn)算的結(jié)果為1時,我們才進(jìn)行計算,為0時不計算,所以我們還需要一個條件語句進(jìn)行判斷即:
for (int i = 0; i< (1<< N); i++) // i用于統(tǒng)計各種情況
{for (int j = 0; j< N; j++)
{if ((i >>j) & 1) //通過與1進(jìn)行與運(yùn)算,來對所有情況進(jìn)行求和
{ }
}
if (sum == K && count == M)//打印結(jié)果
{……
}
}
最后我們的最終代碼應(yīng)該為
#include#define N 20
int main()
{int sum; //用來計算M個元素之和
int count; //用來統(tǒng)計已經(jīng)相加的元素個數(shù),用于判斷是否和M相等
int flag = 0; //用來標(biāo)記結(jié)果,1表示數(shù)組a中有M個元素其和為K,0表示沒有
int M, K;
int a[N] = {21, 1, 35, 15, 32, 12, 5, 7};
scanf("%d %d", &M, &K);
for (int i = 0; i< (1<< N); i++) // i用于統(tǒng)計各種情況
{sum = 0;
count = 0; //每結(jié)束一次循環(huán),sum、count都需要重新置零
for (int j = 0; j< N; j++)
{if ((i >>j) & 1) //通過與1進(jìn)行與運(yùn)算,來對所有情況進(jìn)行求和
{sum += a[j];
count++;
}
}
if (sum == K && count == M)//打印結(jié)果
{flag = 1;
count = 0;
printf("數(shù)組a中存在%d個元素其和為%d\n", M, K);
for (int j = 0; j< N; j++)
{if ((i >>j) & 1)
{count++;
if (count == M)
printf("%d", a[j]);
else
printf("%d+", a[j]);
}
}
printf("=%d\n", K);
break;
}
}
if (flag == 0)//如果數(shù)組中不存在M個元素其和為K
{printf("數(shù)組a中不存在%d個元素其和為%d\n", M, K);
}
}
我們對代碼進(jìn)行編譯與運(yùn)行,結(jié)果為:
如有錯誤,請批評指出,希望各位大佬指點(diǎn)
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧