思想:
1 找出3数和为26的所有组合(3个数范围在1-14)
2 7条边 用1中的组合试 邻边有且只有1个数相同
实现的时候:flag用于剔除重复,第N位表示N,比如flag=(0000011010)b 即表示(1,3,4)的组合
[ 本帖最后由 njkido 于 2011-4-9 02:19 编辑 ]
1 找出3数和为26的所有组合(3个数范围在1-14)
2 7条边 用1中的组合试 邻边有且只有1个数相同
实现的时候:flag用于剔除重复,第N位表示N,比如flag=(0000011010)b 即表示(1,3,4)的组合
程序代码:
// TempTemp.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #define MY_DEBUG (0) #define MAX_ROW (100) #define NUM_MAX (14) #define SIDES_SUM (26) int SideCombArray[MAX_ROW][3] = {0}; int SideCombFlag[MAX_ROW] = {0}; inline int GetSideCombFlag(int i, int j, int k) { int flag = 0; flag |= 1<<i; flag |= 1<<j; flag |= 1<<k; return flag; } bool IsSideCombAlreadyExist(int SideCombFlag[MAX_ROW],int FlagToVerify, int Count) { int i = 0; for (i=0; i<Count; i++) { if (SideCombFlag[i] == FlagToVerify) { return true; } } return false; } int SideCombCount = 0; void GenSideSumArray() { int i = 0; int j = 0; int k = 0; for (i=1; i<=NUM_MAX; i++) { for (j=1; j<=NUM_MAX; j++) { if (j==i) continue; for (k=1; k<=NUM_MAX; k++) { if (k==i || k==j) continue; if (SIDES_SUM == i+j+k) { int Flag = GetSideCombFlag(i,j,k); if (!IsSideCombAlreadyExist(SideCombFlag, Flag, SideCombCount)) { SideCombFlag[SideCombCount] = Flag; SideCombArray[SideCombCount][0] = i; SideCombArray[SideCombCount][1] = j; SideCombArray[SideCombCount++][2] = k; #if MY_DEBUG printf("%d + %d + %d = %d\n",i,j,k,SIDES_SUM); #endif } } } } } #if MY_DEBUG printf("Count = %d\n\n",SideCombCount); #endif return; } bool IsSideCombAlreadyPicked(int Side[7], int SideIndex, int FlagIndex) { int i = 0; for (i=0; i<7; i++) { if (i != SideIndex && Side[i] == FlagIndex) { return true; } } return false; } bool IsOnlySameOne(int FlagIndex1, int FlagIndex2) { int FlagTemp = SideCombFlag[FlagIndex1] & SideCombFlag[FlagIndex2]; int i = 0; int Count = 0; for (i=1; i<=14; i++) { if (FlagTemp & (1<<i)) { Count++; if (Count > 1) { return false; } } } return (Count == 1); } bool IsSideCaseOk(int Side[7]) { int i = 0; int NumCount[14] = {0}; int PointCount = 0; for (i=0; i<7; i++) { NumCount[SideCombArray[Side[i]][0]-1]++; NumCount[SideCombArray[Side[i]][1]-1]++; NumCount[SideCombArray[Side[i]][2]-1]++; } for (i=0; i<14; i++) { if (NumCount[i] == 0 || NumCount[i] > 2) { return false; } if (NumCount[i] == 2) { PointCount++; } } if (PointCount != 7) { return false; } return true; } int GetTopPoint(int Side[7], int SideIndex) { int i = 0; int PrevIndex = (SideIndex - 1 + 7) % 7; int Point = SideCombFlag[Side[SideIndex]] & SideCombFlag[Side[PrevIndex]]; for (i=1; i<=14; i++) { if (Point & (1<<i)) { return i; } } return -1; } void PrintSeven(int Side[7]) { int i = 0; int Point[14] = {0}; printf("\nfind!\n"); for (i=0; i<7; i++) { Point[i*2] = GetTopPoint(Side,i); if (i) { Point[i*2-1] = SIDES_SUM - Point[i*2] - Point[i*2 - 2]; printf("第%d条边: %d--%d--%d\n",i,Point[i*2 - 2],Point[i*2 - 1],Point[i*2]); } } Point[i*2 - 1] = SIDES_SUM - Point[0] - Point[i*2 - 2]; printf("第%d条边: %d--%d--%d\n",i,Point[i*2 - 2],Point[i*2 - 1],Point[0]); return; } void ChooseSide() { int Side[7] = {0}; for (Side[0]=0; Side[0]<SideCombCount; Side[0]++) { for (Side[1]=0; Side[1]<SideCombCount; Side[1]++) { if (IsSideCombAlreadyPicked(Side, 1, Side[1])) continue; if (!IsOnlySameOne(Side[1],Side[0])) continue; for (Side[2]=0; Side[2]<SideCombCount; Side[2]++) { if (IsSideCombAlreadyPicked(Side, 2, Side[2])) continue; if (!IsOnlySameOne(Side[2],Side[1])) continue; for (Side[3]=0; Side[3]<SideCombCount; Side[3]++) { if (IsSideCombAlreadyPicked(Side, 3, Side[3])) continue; if (!IsOnlySameOne(Side[3],Side[2])) continue; for (Side[4]=0; Side[4]<SideCombCount; Side[4]++) { if (IsSideCombAlreadyPicked(Side, 4, Side[4])) continue; if (!IsOnlySameOne(Side[4],Side[3])) continue; for (Side[5]=0; Side[5]<SideCombCount; Side[5]++) { if (IsSideCombAlreadyPicked(Side, 5, Side[5])) continue; if (!IsOnlySameOne(Side[5],Side[4])) continue; for (Side[6]=0; Side[6]<SideCombCount; Side[6]++) { if (IsSideCombAlreadyPicked(Side, 6, Side[6])) continue; if (!IsOnlySameOne(Side[6],Side[5])) continue; if (!IsOnlySameOne(Side[0],Side[6])) continue; if (IsSideCaseOk(Side)) { #if MY_DEBUG printf("1th: %d-%d-%d\n",SideCombArray[Side[0]][1],SideCombArray[Side[0]][2],SideCombArray[Side[0]][3]); printf("7th: %d-%d-%d\n",SideCombArray[Side[6]][1],SideCombArray[Side[6]][2],SideCombArray[Side[6]][3]); #endif PrintSeven(Side); } } } } } } } } } int main() { GenSideSumArray(); ChooseSide(); return 0; }
[ 本帖最后由 njkido 于 2011-4-9 02:19 编辑 ]