拯救少林神棍 代码有注释

来源:互联网 发布:知乎网源码 编辑:程序博客网 时间:2024/04/27 18:45

拯救少林神棍

#define _CRT_SECURE_NO_WARNINGS#include <iostream>#include <memory.h>#include <stdlib.h>#include <vector>#include <algorithm>#include <functional>   // std::greaterusing namespace std;int T, N;int L;int nLastStickNo;//最近拼上去的那条木棒的下标vector<int> anLength;int anUsed[65];//是否用过的标记int i, j, k;int Dfs(int R, int M);int main(){ while (1) {cin >> N;if (N == 0)break;int nTotalLen = 0;anLength.clear();for (int i = 0; i < N; i++) {int n;cin >> n;anLength.push_back(n);nTotalLen += anLength[i];}sort(anLength.begin(), anLength.end(), greater<int>());//从最长的第一根小棒开始,直到总长度的一半  for (L = anLength[0]; L <= nTotalLen / 2; L++) {if (nTotalLen % L)//如果不可以全拼完 ,L长度就不是continue;memset(anUsed, 0, sizeof(anUsed));if (Dfs(N, L)) {cout << L << endl;break;}}if (L > nTotalLen / 2)//如果大于小棒总长度的一半  输出总长度cout << nTotalLen << endl;} // while return 0;} //nUnusedSticks 还剩小棍数量int Dfs(int nUnusedSticks, int nLeft)// nLeft表示当前正在拼的棍子和 L 比还缺的长度{if (nUnusedSticks == 0 && nLeft == 0)return true;if (nLeft == 0) //一根刚刚拼完nLeft = L;  //开始拼新的一根int nStartNo = 0;if (nLeft != L) //剪枝4nStartNo = nLastStickNo + 1;//nLastStickNo  最近拼上去的那条木棒的下标for (int i = nStartNo; i < N; i++) {//遍历所有小棍if (!anUsed[i] && anLength[i] <= nLeft) {//没有被使用过且 小于棒子还差的长度if (i > 0) {//不是第一根if (anUsed[i - 1] == false && anLength[i] == anLength[i - 1])//前一根没有被使用 且长度一样continue; //剪枝1}anUsed[i] = 1;  nLastStickNo = i;if (Dfs(nUnusedSticks - 1,nLeft - anLength[i]))return true;else {anUsed[i] = 0;//说明本次不能用第i根  //第i根以后还有用if (anLength[i] == nLeft || nLeft == L)return false;//剪枝3、2}}}return false;}

0 0
原创粉丝点击