user-0 提问: 猜数字项目最简算法，比谁的程序猜测总次数最少 

回复:
user: user-1
content: 你这个难度有点大啊

user: user-0
content: 引用 3 楼 kugeniha 的回复:参考下:  #include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> #define M 4 //猜几个数字   //交换  void swap(int*a,int*b)  { 	int t=*a; 	 *a=*b; 	*b=t;  }  //将数组随机打乱   void random_shuffle(int* a,int n)  { 	int i; 	 for(i=0;i<n;i++) 	{ 		int x=rand()%n; 		int y=rand()%n; 		if(x!=y) swap(a+x,a+y); 	}  }   //生成数位不重复的M位全部数据，存在数组a中，并打乱，备用   int  gen(int* a)  { 	int count=0,i,j; 	int max=1; 	for(i=0;i<M;++i,max*=10);  		for(i=0;i<max;++i) 		{ 			int flag[10]={0}; 			int t=i; 			for(j=0;j<M;++j) 				if(flag[t%10]) break; 				else flag[t%10]=1,t/=10; 	if(j==M) 		a[count++]=i;  	} 	random_shuffle(a,count); 	return count; }  void test(int answer,int player,int* A,int* B)  { 	int i=0,j;  	int answer_a[M]={0},player_a[M]={0}; 	*A=*B=0; 	while(answer||player) 	{ 		answer_a[i]=answer%10; 		player_a[i++]=player%10; 		answer/=10; 		player/=10; 	 } 	for(i=0;i<M;++i) 	for(j=0;j<M;++j) 		if(player_a[i]==answer_a[j]) 			if(i==j) ++*A; 			else ++*B; }  //参数AB是上一轮猜测的反馈，  //如果得到猜中的信息表示下一把的开始  int guess(int *a,int n)  {  //你的工作在这个函数  		int A=M,B=0,OA; 		int count_cur=0; 		int i,j,num,p; 		char arr[5],new_arr[5],ch; 		int flag[4]={0}; 		printf("The answer is %d\n",a[n]);//先给出答案，用以验证 		for(i=0,j=0;i<10;i++,++count_cur) 		{ 			if(4==M) 				num=i*1111; 			else  				num=i*111; 			test(a[n],num,&A,&B); 			printf("%d:%0*d,%dA%dB\n",count_cur,M,num,A,B); 			if(A==1) arr[j++]=i+48; 			if(M==j) break; 		}//经此for循环，得出要猜的数由哪些数字组成 		arr[M]=0;//尾0 		num=atoi(arr); 		//printf("%d",numA); 		test(a[n],num,&A,&B); 		count_cur++; 		printf("%d:%0*d,%dA%dB\n",count_cur,M,num,A,B); 		OA=A;//标记上一次猜测的数的位置与数都正确的个数 		if(A==M&&B==0) 		{ 			printf("答案是%s\n",arr); 			return count_cur; 		}//如果猜测与答案一样，显示答案，返回猜测步数 		p=0; 		for(i=0;i<M;i=p) 		{ 			strncpy(new_arr,arr,M); 			new_arr[M]=0; 			if(0==flag[i])//定义数组flag初始为0,表示对应下标的位置不正确，正确了后置1 			{ 				for(j=i+1;j<M;j++) 				{ 					if(0==flag[j]) 					{ 						new_arr[j]=arr[i]; 						num=atoi(new_arr); 						//printf("num=%d\n",num); 						count_cur++; 						test(a[n],num,&A,&B); 						printf("%d:%0*d,%dA%dB\n",count_cur,M,num,A,B); 						if(A>OA) //arr[i]在此次j位上，交换 						{ 							flag[j]=1; 							ch=arr[j]; 							arr[j]=arr[i]; 							arr[i]=ch; 							num=atoi(arr); 							count_cur++; 							test(a[n],num,&A,&B);//交换之后0A有可能在原基础上加1，也可能加二，所以直接调用test算出准确OA 							printf("%d:%0*d,%dA%dB\n",count_cur,M,num,A,B); 							OA=A; 							p=i; 							break; 						} 						else if(A<OA) //说明此位置原本数对应正确的位置，不可改变，对应下标置1 						{	 							flag[j]=1; 							new_arr[j]=arr[j]; 						} 					} 				}//找正确位置 				if(M==j)  				{ 					flag[i]=1; 					p=i+1; 				}//一轮for循环，没找到正确位置，说明本身所在的位置是正确的。 			} 			else p=i+1; 			//printf("p=%d\n",p); 		} 		printf("答案是%s\n",arr); 		return count_cur;  }  int main()  {     int i;  //初始生成数据      int len; 	int *a; 	int  n=3,nn=n;//玩n把     int count=0;//总猜测次数     for(len=1,i=0;i<M;++i)     len*=10-i;     a=(int *)malloc(sizeof(int)*len);	 	srand((unsigned)time(NULL)); 	//srand(2);     gen(a);  //开玩     while(n--)     { 		int count_cur=0;      //每把从猜中开始，例如玩4个数，4A0B为猜中， //此时进入下一把，会有新的数供猜测   //printf("%d\n",a[n]); 		count_cur=guess(a,n); 		printf("此轮共%d步完成\n",count_cur); 		count+=count_cur;     } 	printf("游戏结束,共计%d轮游戏,总消耗%d步\n",nn,count); 	system("pause");     return 0;  }    老哥 还能再优化一下吗，步数能减少一点就减少一点，注释再稍微详细一点，我是萌新看不懂现在就可以把分给你。

user: user-0
content: 老哥这还能再优化一下吗，步数能减少一点就减少一点，注释再稍微详细一点，我是萌新看不懂现在就可以把分给你。

user: user-2
content: 参考下:  #include <stdio.h> #include <stdlib.h> #include <time.h> #include <string.h> #define M 4 //猜几个数字   //交换  void swap(int*a,int*b)  { 	int t=*a; 	 *a=*b; 	*b=t;  }  //将数组随机打乱   void random_shuffle(int* a,int n)  { 	int i; 	 for(i=0;i<n;i++) 	{ 		int x=rand()%n; 		int y=rand()%n; 		if(x!=y) swap(a+x,a+y); 	}  }   //生成数位不重复的M位全部数据，存在数组a中，并打乱，备用   int  gen(int* a)  { 	int count=0,i,j; 	int max=1; 	for(i=0;i<M;++i,max*=10);  		for(i=0;i<max;++i) 		{ 			int flag[10]={0}; 			int t=i; 			for(j=0;j<M;++j) 				if(flag[t%10]) break; 				else flag[t%10]=1,t/=10; 	if(j==M) 		a[count++]=i;  	} 	random_shuffle(a,count); 	return count; }  void test(int answer,int player,int* A,int* B)  { 	int i=0,j;  	int answer_a[M]={0},player_a[M]={0}; 	*A=*B=0; 	while(answer||player) 	{ 		answer_a[i]=answer%10; 		player_a[i++]=player%10; 		answer/=10; 		player/=10; 	 } 	for(i=0;i<M;++i) 	for(j=0;j<M;++j) 		if(player_a[i]==answer_a[j]) 			if(i==j) ++*A; 			else ++*B; }  //参数AB是上一轮猜测的反馈，  //如果得到猜中的信息表示下一把的开始  int guess(int *a,int n)  {  //你的工作在这个函数  		int A=M,B=0,OA; 		int count_cur=0; 		int i,j,num,p; 		char arr[5],new_arr[5],ch; 		int flag[4]={0}; 		printf("The answer is %d\n",a[n]);//先给出答案，用以验证 		for(i=0,j=0;i<10;i++,++count_cur) 		{ 			if(4==M) 				num=i*1111; 			else  				num=i*111; 			test(a[n],num,&A,&B); 			printf("%d:%0*d,%dA%dB\n",count_cur,M,num,A,B); 			if(A==1) arr[j++]=i+48; 			if(M==j) break; 		}//经此for循环，得出要猜的数由哪些数字组成 		arr[M]=0;//尾0 		num=atoi(arr); 		//printf("%d",numA); 		test(a[n],num,&A,&B); 		count_cur++; 		printf("%d:%0*d,%dA%dB\n",count_cur,M,num,A,B); 		OA=A;//标记上一次猜测的数的位置与数都正确的个数 		if(A==M&&B==0) 		{ 			printf("答案是%s\n",arr); 			return count_cur; 		}//如果猜测与答案一样，显示答案，返回猜测步数 		p=0; 		for(i=0;i<M;i=p) 		{ 			strncpy(new_arr,arr,M); 			new_arr[M]=0; 			if(0==flag[i])//定义数组flag初始为0,表示对应下标的位置不正确，正确了后置1 			{ 				for(j=i+1;j<M;j++) 				{ 					if(0==flag[j]) 					{ 						new_arr[j]=arr[i]; 						num=atoi(new_arr); 						//printf("num=%d\n",num); 						count_cur++; 						test(a[n],num,&A,&B); 						printf("%d:%0*d,%dA%dB\n",count_cur,M,num,A,B); 						if(A>OA) //arr[i]在此次j位上，交换 						{ 							flag[j]=1; 							ch=arr[j]; 							arr[j]=arr[i]; 							arr[i]=ch; 							num=atoi(arr); 							count_cur++; 							test(a[n],num,&A,&B);//交换之后0A有可能在原基础上加1，也可能加二，所以直接调用test算出准确OA 							printf("%d:%0*d,%dA%dB\n",count_cur,M,num,A,B); 							OA=A; 							p=i; 							break; 						} 						else if(A<OA) //说明此位置原本数对应正确的位置，不可改变，对应下标置1 						{	 							flag[j]=1; 							new_arr[j]=arr[j]; 						} 					} 				}//找正确位置 				if(M==j)  				{ 					flag[i]=1; 					p=i+1; 				}//一轮for循环，没找到正确位置，说明本身所在的位置是正确的。 			} 			else p=i+1; 			//printf("p=%d\n",p); 		} 		printf("答案是%s\n",arr); 		return count_cur;  }  int main()  {     int i;  //初始生成数据      int len; 	int *a; 	int  n=3,nn=n;//玩n把     int count=0;//总猜测次数     for(len=1,i=0;i<M;++i)     len*=10-i;     a=(int *)malloc(sizeof(int)*len);	 	srand((unsigned)time(NULL)); 	//srand(2);     gen(a);  //开玩     while(n--)     { 		int count_cur=0;      //每把从猜中开始，例如玩4个数，4A0B为猜中， //此时进入下一把，会有新的数供猜测   //printf("%d\n",a[n]); 		count_cur=guess(a,n); 		printf("此轮共%d步完成\n",count_cur); 		count+=count_cur;     } 	printf("游戏结束,共计%d轮游戏,总消耗%d步\n",nn,count); 	system("pause");     return 0;  }

user: user-3
content: 百度搜相关关键字。