Sicily1050(DFS)

先枚举五个数取1个、2个、3个、4个、5个的情况,存在num2数组中。再对num2数组枚举,每次选2个数合并。(0.4s)

/*
 * Cpp0.cpp
 *
 *  Created on: 2014年7月8日
 *      Author: MIAO
 */
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;

int T;
long long num[6],aim;
long long num2[6];
long long record;
long long minn;

void dfs(long long arr[],int length)
{
	if (length==1)
		if (aim-arr[0]>=0 && aim-arr[0]<minn)
		{
			minn=aim-arr[0];
			record=arr[0];
		}
	int i,j,k;
	for (i=0;i<length;i++)
		for (j=i+1;j<length;j++)
		{
			long long A[6];
			int counter=0;
			for (k=0;k<length;k++)
				if (k!=i && k!=j)
					A[counter++]=arr[k];

			A[counter]=arr[i]+arr[j];
			dfs(A,length-1);
			A[counter]=arr[i]*arr[j];
			dfs(A,length-1);
			A[counter]=arr[i]-arr[j];
			dfs(A,length-1);
			A[counter]=arr[j]-arr[i];
			dfs(A,length-1);
			if (arr[j]!=0 && arr[i]%arr[j]==0)
			{
				A[counter]=arr[i]/arr[j];
				dfs(A,length-1);
			}
			if (arr[i]!=0 && arr[j]%arr[i]==0)
			{
				A[counter]=arr[j]/arr[i];
				dfs(A,length-1);
			}
		}
}

void dfs_select(int depth,int length,int pos)
{
	if (depth==length)
	{
		dfs(num2,length);
		return;
	}
	int i;
	for (i=pos;i<5;i++)
	{
		num2[depth]=num[i];
		dfs_select(depth+1,length,i+1);
	}
}

int main()
{
	scanf("%d",&T);
	int i;
	while (T--)
	{
		minn=91000000000;
		for (i=0;i<5;i++)
			scanf("%lld",&num[i]);
		scanf("%lld",&aim);

		int length;
		for (length=1;length<=5;length++)
			dfs_select(0,length,0);
		printf("%lld\n",record);
	}
}



优化了一下,实际上不用先枚举一次,可以在枚举num2的过程中进行判断。每次递归不重新开数组,只是调换顺序,且long long改为int,运行时间快很多,0.12s。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;

int T;
int arr[6],aim;
int maxn;

void dfs(int length,int pos)
{
	if (arr[pos]<=aim && arr[pos]>maxn)
		maxn=arr[pos];
	if (maxn==aim) return;
	if (length==1) return;
	int i,j;
	int tempi,tempj;
	for (i=0;i<length;i++)
		for (j=i+1;j<length;j++)
		{
			tempi=arr[i];
			tempj=arr[j];
			arr[j]=arr[length-1];

			arr[i]=tempi+tempj;
			dfs(length-1,i);
			arr[i]=tempi*tempj;
			dfs(length-1,i);
			arr[i]=tempi-tempj;
			dfs(length-1,i);
			arr[i]=tempj-tempi;
			dfs(length-1,i);
			if (tempj!=0 && tempi%tempj==0)
			{
				arr[i]=tempi/tempj;
				dfs(length-1,i);
			}
			if (tempi!=0 && tempj%tempi==0)
			{
				arr[i]=tempj/tempi;
				dfs(length-1,i);
			}
			arr[i]=tempi;
			arr[j]=tempj;
		}
}

int main()
{
	scanf("%d",&T);
	int i;
	while (T--)
	{
		maxn=-0x7fffffff;
		for (i=0;i<5;i++)
			scanf("%d",&arr[i]);
		scanf("%d",&aim);
		dfs(5,0);
		printf("%d\n",maxn);
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值