2023XTU程设练习三

程设勉强过了,感谢谢大,其实练习三没写几道题,太难了不会,考试也没写出来这些知识的题qwq,主要程设过了就不想写代码了,开摆~

猜数字

Submit Code ] [ Top 20 Runs ] [ Runs Status ]
Acceteped : 693Submit : 1269
Time Limit : 10000 MSMemory Limit : 65536 KB

Description

题目描述

猜数字游戏是这样的,主持人先从1~N个数字,随意取4个数字,组成一个序列。 然后你猜了K次,每次你依次报4个数字。主持人告诉你数字和位置都对的数字有x个,数字对但位置不对的数字有y个。 请问你满足这K次询问的数字序列有几个?分别是什么?

输入

有多个样例。第一行是一个整数N,(4≤N≤50),如果N为0,表示输入结束,这个样例不用处理。 第二行是一个整数K,(10≤k≤100),表示询问的次数。 以后的K行,每行6个整数,前4个表示你报的数字序列,每个数字在1到N之间,且没有重复,最后两个整数为x和y。(0≤x+y≤N)

输出

每个样例按数字序列的字典序输出满足序列,每个序列占一行,每个整数之间用一个空格隔开,行末没空格。最后输出这些序列的总数。

样例输入

4
1 
1 2 3 4 4 0
0

样例输出

1 2 3 4
1

这个题,虽然穷举暴力也不会超时,我按题解的回溯来写了下

#include <stdio.h>
//#include <vector>
#include <algorithm>
//typedef __int64 ll;
#include <string.h>
using namespace std;
	int n, k, ans;
	int a[5], b[105][8];
	int used[55];
	int answer[2005][6];
	bool check(){
	    int x = 0, y = 0,c = 0,flag=0;
			for(c=1;c<=k;c++){
				x=0,y=0;
				for (int i = 1; i <= 4; i++)
					{
						if (a[i] == b[c][i]) x++;
						if(x>b[c][5]) return false;
						for (int j = 1; j <= 4; j++)
						{
							if (i == j) continue;
							if (a[i] == b[c][j]) y++;
							if(y>b[c][6]) return false;
						}
					}
				if (x == b[c][5] && y == b[c][6]) //判断是否符合条件
				{
					flag++;
				}					
			}
	       
	    if(flag==k) return true;
	    else return false;
	}
	bool check2(int step){
		int x = 0, y = 0,c = 1,flag=0;
					for(c=1;c<=k;c++){
						x=0;y=0;
						for (int i = 1; i <= step; i++)
							{
								if (a[i] == b[c][i]) x++;
								if(x>b[c][5]) return 0;
								for (int j = 1; j <= step; j++)
								{
									if (i == j) continue;
									if (a[i] == b[c][j]) y++;
									if(y>b[c][6]) return 0;
								}
							}
//							printf("x=%d y=%d\n",x,y);
//							printf("b[c][5]=%d b[c][6]=%d\n",b[c][5],b[c][6]);
						if (x <= b[c][5] && y <= b[c][6]) //判断是否符合条件
						{
							flag++;
						}							
					}
//			       printf("flag=%d k=%d\n",flag,k);
			    if(flag!=k) return false;
			    else return true;
	}
	void dfs(int step)
	{
		if (step == 5)
		{
//			cout<<"1 "<<endl;
			if(check()){
				ans++; //符合条件的方案数+1
				for (int i = 1; i <= 4; i++)
				{
//					printf("%d ",a[i]);
					answer[ans-1][i]=a[i];
				}
//				printf("\n");
			}
		}
		else{
//		L1:	
			for (int i = 1; i <= n; i++)
				{
					if (!used[i])
					{
//							cout<<"step="<<step<<"i="<<i<<endl;
							a[step] = i;
							if(check2(step)){
//								printf("step=%d,i=%d\n",step,i);
								used[i] = 1;
								dfs(step+1);
								used[i] = 0;
							}
//							else printf("fs  step=%d,i=%d\n",step,i);				
					}
				}
		}
	}
	int main()
	{
//	ios::sync_with_stdio(false);//加快cin,cout的速度
	while (1)
	{
		scanf("%d",&n);
		if(n==0) break;
		scanf("%d",&k);
		ans = 0;
		for(int j=1;j<=k;j++){
			for (int i = 1; i <= 4; i++)
				{
					scanf("%d",&b[j][i]);
				}
				scanf("%d%d",&b[j][5],&b[j][6]);
		}
			memset(a, 0, sizeof(a));
		    memset(answer, 0, sizeof(answer));
			memset(used, 0, sizeof(used));
			dfs(1);
			for(int i=0;i<ans;i++){
				for(int j=1;j<=4;j++){
					if(j!=4) printf("%d ",answer[i][j]);
					else printf("%d",answer[i][j]);
				}
				printf("\n");
			}
		
			printf("%d\n",ans);
	}
	return 0;
	}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值