user-0 提问: 数学测试，用C描述，题目来了！分高点当散小分

回复:
user: user-1
content: #!/usr/bin/python  all = [ [a, b, c, d, e]     for a in range(1, 7)     for b in range(1, 7)     for c in range(1, 7)     for d in range(1, 7)     for e in range(1, 7) ]  def check(a):     b = [         abs(a[0] - a[1]),         abs(a[1] - a[2]),         abs(a[2] - a[3]),         abs(a[3] - a[4]) ]     return len(set(a)) > 2 and 5 not in b  count = 0  for a in all:     if check(a):         count += 1  print count  用python写了个穷举，结果是5880没错。 如果是穷举，那么主要还是两个判断条件要写对。 如果是当数学问题，那么复习下排列组合吧。

user: user-2
content: 围观5楼大神.

user: user-0
content: 谢谢大家辛苦帮忙啦，总算解决了问题，谢谢各位，爱CSDN！

user: user-3
content: 输出行数太多，控制台显示不了，可加头文件 #include <Windows.h>，然后在main()中加入如下代码：  HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 控制台窗口句柄 	COORD bufferSize = { 0 };  	system("mode con cols=65 lines=25");  	bufferSize.X = 80; bufferSize.Y = 6000; 	SetConsoleScreenBufferSize(hOut, bufferSize);

user: user-3
content: 补个能完整输出所有组合的：  #include <stdio.h> #include <math.h>  int jdg1(int *p);//判断“相邻的两槽的高度差不能为5” int jdg2(int *p);//判断“至少有3个不同的数”  int main() { 	int a[6], num = 0;// a[1]到a[5]分别为5个槽的高度，num为符合条件的组合数 	for (a[1] = 1; a[1] < 7; a[1]++) 	{ 		for (a[2] = 1; a[2] < 7; a[2]++) 		{ 			for (a[3] = 1; a[3] < 7; a[3]++) 			{ 				for (a[4] = 1; a[4] < 7; a[4]++) 				{  					for (a[5] = 1; a[5] < 7; a[5]++) 					{ 						if (jdg1(a) && jdg2(a)) 						{ 							for (int i = 1; i < 6; i++) 							{ 								printf("%d ", a[i]); 							} 							printf("-- %d\n", ++num); 						} 					}  				}  			} 		} 	}  	return 0; }  int jdg1(int *p) { 	for (int i = 1; i < 5; i++) 	{ 		if (abs(*(p + i) - *(p + i + 1)) == 5) 			return 0; 	} 	return 1; }  int jdg2(int *p) { 	int i, b[7], count = 0; 	for (i = 1; i < 7; i++) 		b[i] = 0; 	for (i = 1; i < 6; i++) 		b[*(p + i)]++; 	for (i = 1; i < 7; i++) 	{ 		if (b[i] == 0) 			count++; 	} 	if (count>3) 		return 0; 	return 1; }

user: user-3
content: 应该就是这样：  #include <stdio.h> #include <math.h>  int jdg1(int *p);//判断“相邻的两槽的高度差不能为5” int jdg2(int *p);//判断“至少有3个不同的数”  int main() { 	int a[6], num = 0;// a[1]到a[5]分别为5个槽的高度，num为符合条件的组合数 	for (a[1] = 1; a[1] < 7; a[1]++) 	{ 		for (a[2] = 1; a[2] < 7; a[2]++) 		{ 			for (a[3] = 1; a[3] < 7; a[3]++) 			{ 				for (a[4] = 1; a[4] < 7; a[4]++) 				{  					for (a[5] = 1; a[5] < 7; a[5]++) 					{ 						if (jdg1(a) && jdg2(a)) 								num++; 					}  				}  			} 		} 	} 	printf("符合条件的组合有：%d 个\n", num);  	return 0; }  int jdg1(int *p) { 	for (int i = 1; i < 5; i++) 	{ 		if (abs(*(p + i) - *(p + i + 1)) == 5) 			return 0; 	} 	return 1; }  int jdg2(int *p) { 	int i, b[7], count = 0;//b[1] 	for (i = 1; i < 7; i++) 		b[i] = 0; 	for (i = 1; i < 6; i++) 		b[*(p + i)]++; 	for (i = 1; i < 7; i++) 	{ 		if (b[i] == 0) 			count++; 	} 	if (count>3) 		return 0; 	return 1; }

user: user-4
content: // ConsoleApplication6.cpp : 定义控制台应用程序的入口点。 //  #include "stdafx.h" #include<cstdlib> #include<cmath> #include <vector> #include <set> #include <iostream> using namespace std;  bool Check(vector<int> &vi) { 	if (vi.size() != 5) 		return false; 	 	set<int>sc(vi.begin(), vi.end()); 	if (sc.size() < 3) 		return false;  	for (int i = 0; i < vi.size()-1;i++) 	{ 		if (abs(vi[i] - vi[i + 1]) == 5) 			return false; 	}  	return true; }  void Print(vector<int> &vi) {    for (vector<int>::iterator it = vi.begin(); it != vi.end();it++)    { 	   cout << *it << "\t";    }    cout << endl; }  void Qiujie(vector<int> &vi,int &nCount) {    if (vi.size()==5)    { 	   if (Check(vi)) 	   { 		   Print(vi); 		   nCount++; 	   } 	   return;    }     for (int i = 1; i <= 6;i++)    { 	   vi.push_back(i); 	   Qiujie(vi,nCount); 	   vi.pop_back();    }  }  int _tmain(int argc, _TCHAR* argv[]) { 	vector<int> vi; 	int iCount = 0; 	Qiujie(vi, iCount); 	cout << iCount << endl; 	system("pause"); 	return 0; }  加班看到此题，闲着无聊也写一下 C++代码，答案是5880个

user: user-5
content: 引用 16 楼 u010957746 的回复:各位大大哥哥，我改了下代码后，结果得到5880的数据，但是还是有一些问题，没找到出错的原因。 代码如下： 最后出现了6 6 6 6 6 这样的数据 还有5880的重复数据，请教应该如何解决~先谢。敬上  if( (i!=j && i!=k && j!=k) || (i!=j && i!=n && j!=n) || (i!=j && i!=m && j!=m) || (j!=k && j!=n && k!=n) || (j!=k && j!=m && k!=m) || (k!=n && k!=m && n!=m) || (i!=j && i!=k && i!=n && i!=m && j!=k && j!=n && j!=m && k!=n && k!=m && n!=m)   最后一个()中的比较是怎么回事？你要想用暴力比较，就直接列10个表达式进行||, 每个表达式都是3个元素两两不等(5中取3的组合数是10) 或者参考我写的check()函数，用一个辅助数组计数。

user: user-5
content: 顺便说一下，别用vc6.0了。和标准差别比较大，会养成坏习惯的。

user: user-0
content: 各位大大哥哥，我改了下代码后，结果得到5880的数据，但是还是有一些问题，没找到出错的原因。 代码如下： #include<stdio.h> #include<math.h> int main(int argc,char *argv[]) { 	//int sert; 	int i,j,k,n,m; 	int num=0; 	for(i=1;i<=6;i++) 	{ 		for(j=1;j<=6;j++) 		{ 			for(k=1;k<=6;k++) 			{ 				for(n=1;n<=6;n++) 				{ 					for(m=1;m<=6;m++) 					{	 						if( abs(i-j) < 5 && abs(j-k) < 5 && abs(k-n) < 5 && abs(n-m) < 5 ) 						{ 							  if( (i!=j && i!=k && j!=k) || (i!=j && i!=n && j!=n) || (i!=j && i!=m && j!=m) || (j!=k && j!=n && k!=n) || (j!=k && j!=m && k!=m) || (k!=n && k!=m && n!=m) || (i!=j && i!=k && i!=n && i!=m && j!=k && j!=n && j!=m && k!=n && k!=m && n!=m) )//暴力不等	 								num++;		 							//printf("%d\n",num); 							printf("[%d,%d,%d,%d,%d]---%d\n",i,j,k,n,m,num); 							 						} 					} 				} 			} 		} 	}		 	return 0; }   最后出现了6 6 6 6 6 这样的数据 还有5880的重复数据，请教应该如何解决~先谢。敬上

user: user-5
content: 引用 6 楼 u010957746 的回复:大哥您好，我在vc6.0环境下运行了一下，什么都不显示是怎么个情况呢，先谢啦。  因为vc6.0是不符合c标准的。你把代码里2处初始化改一下试试。 int v[M] = {0, 0, 0, 0, 0, 0};  int v[N] = {0, 0, 0, 0, 0}; c标准里定义初始化数组时，元素不足时都初始化成0；vc6.0会初始化成0xCD

user: user-0
content: 引用 10 楼 u010030181 的回复:按照你的思路，写了个并不高明的算法，仅供参考！#include <stdio.h> #include <math.h>   #include<stdlib.h>   int main(int argc,char *argv[]) { 	//int sert; 	int i,j,k,n,m; 	int num=0; 	int arry[6] = {7,7,7,7,7,7};	//这个取值随便，只要值不是0-5即可  	for(i=1;i<=6;i++) 	{ 		for(j=1;j<=6;j++) 		{ 			for(k=1;k<=6;k++) 			{ 				for(n=1;n<=6;n++) 				{ 					for(m=1;m<=6;m++) 					{	 						if (abs(i - j) < 5 && abs(j - k) <  5 && abs(k -n) <  5 && abs(n - m) <  5) 						{ 				 			arry[i -1] = i- 1; 							arry[j-1] = j-1; 							arry[k-1] = k-1; 							arry[m-1] = m-1; 							arry[n-1] = n-1; 							int count = 0; 							for (int tmp = 0; tmp < 6; tmp++) 							{ 								if (arry[tmp] == 7) 									++count; 							} 							 							if (count <= 3) 							{ 								num++;		 								//printf("%d\n",num); 								printf("[%d,%d,%d,%d,%d]---%d\n",i,j,k,n,m,num); 								count = 0;	 							} 														 							for (int tmp = 0; tmp < 6; tmp++)	//记得一定要重新初始化  							{ 								arry[tmp] = 7; 									 							} 															 						} 					} 				} 			} 		} 	}		 	return 0;	 } 学习下，研究看看。

user: user-0
content: 引用 9 楼 hilevel 的回复:用最笨的方法遍历所有的情况，结果是6500.... 然后把所有情况都写到文件里了，也没发现不对的地方，就这样吧  #include <stdlib.h> #include <math.h> #include <stdio.h>  const int iSlotNum=5; const int iMinHeight=1; const int iMaxHeight=6; const int iMinDiff=3; const int iMinu=5;  int main(int argc,char *argv[]) { 	//将每种可能的组合视作一个5进制数，对应十进制的0到6^5-1 	int step=iMaxHeight-iMinHeight+1; 	int numsta=0; 	int numend=pow((float)step,iSlotNum)-1; 	int count=0;  	FILE* file=fopen("d:\output.txt","w+"); 	for (int num=numsta;num<=numend;num++) 	{ 		int height[iSlotNum]; 		int tmpnum=num; 		int diff=iSlotNum; 		bool s=true;  		for (int i=0;i<iSlotNum;i++) 		{ 			//将10进制数转换成5进制数，获取每个孔的值 			height[i]=tmpnum%step+iMinHeight; 			tmpnum=(tmpnum-height[i]+iMinHeight)/step;  			printf("%d\t",height[i]); 			fprintf(file,"%d\t",height[i]);  			if (s) 			{ 				//差距必小于5 				if (i>0 && height[i]-height[i-1]>=iMinu) 				{ 					s=false; 				} 				else 				{ 					//计算相异的个数 					for (int j=0;j<i;j++) 					{ 						if (height[i]==height[j]) 						{ 							diff--; 							s=diff>=iMinDiff; 							break; 						} 					} 				} 			} 		}  		if (s) 		{ 			count++; 		}  		printf("%s\n",s?"符合":"不符合"); 		fprintf(file,"%s\n",s?"符合":"不符合"); 	}  	printf("%d",count); 	fprintf(file,"%d",count); 	fclose(file);  	system("pause" ); 	return 0; } 一开始我得出来的是7776。。。也是有一些问题没有考虑明白。

user: user-6
content: 按照你的思路，写了个并不高明的算法，仅供参考！#include <stdio.h> #include <math.h>   #include<stdlib.h>   int main(int argc,char *argv[]) { 	//int sert; 	int i,j,k,n,m; 	int num=0; 	int arry[6] = {7,7,7,7,7,7};	//这个取值随便，只要值不是0-5即可  	for(i=1;i<=6;i++) 	{ 		for(j=1;j<=6;j++) 		{ 			for(k=1;k<=6;k++) 			{ 				for(n=1;n<=6;n++) 				{ 					for(m=1;m<=6;m++) 					{	 						if (abs(i - j) < 5 && abs(j - k) <  5 && abs(k -n) <  5 && abs(n - m) <  5) 						{ 				 			arry[i -1] = i- 1; 							arry[j-1] = j-1; 							arry[k-1] = k-1; 							arry[m-1] = m-1; 							arry[n-1] = n-1; 							int count = 0; 							for (int tmp = 0; tmp < 6; tmp++) 							{ 								if (arry[tmp] == 7) 									++count; 							} 							 							if (count <= 3) 							{ 								num++;		 								//printf("%d\n",num); 								printf("[%d,%d,%d,%d,%d]---%d\n",i,j,k,n,m,num); 								count = 0;	 							} 														 							for (int tmp = 0; tmp < 6; tmp++)	//记得一定要重新初始化  							{ 								arry[tmp] = 7; 									 							} 															 						} 					} 				} 			} 		} 	}		 	return 0;	 }

user: user-7
content: 用最笨的方法遍历所有的情况，结果是6500.... 然后把所有情况都写到文件里了，也没发现不对的地方，就这样吧  #include <stdlib.h> #include <math.h> #include <stdio.h>  const int iSlotNum=5; const int iMinHeight=1; const int iMaxHeight=6; const int iMinDiff=3; const int iMinu=5;  int main(int argc,char *argv[]) { 	//将每种可能的组合视作一个5进制数，对应十进制的0到6^5-1 	int step=iMaxHeight-iMinHeight+1; 	int numsta=0; 	int numend=pow((float)step,iSlotNum)-1; 	int count=0;  	FILE* file=fopen("d:\output.txt","w+"); 	for (int num=numsta;num<=numend;num++) 	{ 		int height[iSlotNum]; 		int tmpnum=num; 		int diff=iSlotNum; 		bool s=true;  		for (int i=0;i<iSlotNum;i++) 		{ 			//将10进制数转换成5进制数，获取每个孔的值 			height[i]=tmpnum%step+iMinHeight; 			tmpnum=(tmpnum-height[i]+iMinHeight)/step;  			printf("%d\t",height[i]); 			fprintf(file,"%d\t",height[i]);  			if (s) 			{ 				//差距必小于5 				if (i>0 && height[i]-height[i-1]>=iMinu) 				{ 					s=false; 				} 				else 				{ 					//计算相异的个数 					for (int j=0;j<i;j++) 					{ 						if (height[i]==height[j]) 						{ 							diff--; 							s=diff>=iMinDiff; 							break; 						} 					} 				} 			} 		}  		if (s) 		{ 			count++; 		}  		printf("%s\n",s?"符合":"不符合"); 		fprintf(file,"%s\n",s?"符合":"不符合"); 	}  	printf("%d",count); 	fprintf(file,"%d",count); 	fclose(file);  	system("pause" ); 	return 0; }

user: user-0
content: 引用 7 楼 user-8 的回复:这是数学问题吧  是的呢版主大大，想用C来实现，数学问题中的A64什么的都忘记啦，嘿嘿，求帮助啦~

user: user-8
content: 这是数学问题吧

user: user-0
content: 引用 5 楼 truelance 的回复:#include <stdio.h>  #define N 5 #define M 6 #define abs(x) ((x)>0?(x):-(x))  int check(int x[]) {     int idx;     int v[M] = {0};     int num = 0;          for (idx = 0; idx < N-1; idx++)     {         if (abs(x[idx] - x[idx+1]) >= 5) return 0;         v[x[idx]] = 1;     }     v[x[N-1]] = 1;          for (idx = 0; idx < M; idx++)         if (v[idx] == 1) num++;     if (num >= 3)         return 1;     else         return 0; }  int main(void) {     int x[N] = {0};     int num = 0;     int idx = 0;      while (idx >=0)     {         if (++x[idx] <= M)         {             ++idx;             if (idx >= N)             {                 if (check(x)) num++;                 --idx;             }             else             {                 x[idx] = 0;             }         }         else         {             --idx;         }     }          printf("num = %d\n", num);     return 0; }    大哥您好，我在vc6.0环境下运行了一下，什么都不显示是怎么个情况呢，先谢啦。

user: user-5
content: #include <stdio.h>  #define N 5 #define M 6 #define abs(x) ((x)>0?(x):-(x))  int check(int x[]) {     int idx;     int v[M] = {0};     int num = 0;          for (idx = 0; idx < N-1; idx++)     {         if (abs(x[idx] - x[idx+1]) >= 5) return 0;         v[x[idx]] = 1;     }     v[x[N-1]] = 1;          for (idx = 0; idx < M; idx++)         if (v[idx] == 1) num++;     if (num >= 3)         return 1;     else         return 0; }  int main(void) {     int x[N] = {0};     int num = 0;     int idx = 0;      while (idx >=0)     {         if (++x[idx] <= M)         {             ++idx;             if (idx >= N)             {                 if (check(x)) num++;                 --idx;             }             else             {                 x[idx] = 0;             }         }         else         {             --idx;         }     }          printf("num = %d\n", num);     return 0; }

user: user-0
content: 引用 3 楼 zxh707wk 的回复:请贴上你的代码，否则我会认为你是来求代码的伸手党我自认为我的代码实在是太烂了，，都不好意思贴- - #include<stdio.h> int main(int argc,char *argv[]) { 	//int sert; 	int i,j,k,n,m; 	int num=0; 	for(i=1;i<=6;i++) 	{ 		for(j=1;j<=6;j++) 		{ 			for(k=1;k<=6;k++) 			{ 				for(n=1;n<=6;n++) 				{ 					for(m=1;m<=6;m++) 					{	 						if( ( (i==1 && j!=6) || (j==1 && i!=6 && k!=6) || (k==1 && j!=6 && n!=6) || (n==1 && k!=6 && m!=6) || (m==1 && n!=6 )) ) 						{ 							if( ( i!=j && i!=k ) || (i!=j && i!=n) || (i!=j && i!=m) || (j!=k && j!=n) || (j!=k && j!=m) || (k!=n && k!=m) || (i!=j && i!=k && i!=n) || (i!=j && i!=k && i!=m) || (i!=k && i!=n && i!=m) || (j!=k && j!=n && j!=m) || (i!=j && i!=k && i!=n && i!=m && j!=k && j!=n && j!=m && k!=n && k!=m && n!=m) )//300 								num++;		 								//printf("%d\n",num); 								printf("[%d,%d,%d,%d,%d]---%d\n",i,j,k,n,m,num); 						} 					} 				} 			} 		} 	}		 	return 0;	 }  见效了。各位大大。哥哥。