POJ1416 切割纸条(DFS+剪枝)

原创 2013年12月05日 18:54:45


这题目个人感觉有点难,很难抽象出具体的搜索模型,看了别人的解题报告才有思路。

切割一个数据即切割纸条,相加的和最接近给出目标的值。
比如,12346是数据,target的值是50,应该把数字切成四部分,分别是1、2、34、6。因为这样所得到的和43 (= 1 + 2 + 34 + 6) 
是所有可能中最接近而不超过50的。碎纸还有以下三个要求:
1、如果target的值等于纸条上的值,则不能切。
2、如果没有办法把纸条上的数字切成小于target,则输出error。如target是1而纸条上的数字是123,则无论你如何切得到的和都比1大。
3、如果有超过一种以上的切法得到最佳值,则输出rejected。如target为15,纸条上的数字是111,则有以下两种切法11、1或者1、

 2140K 32MS C++ 2636B 2013-12-05 18:14:25


下面是代码:


#include<iostream>
#include<vector>
#include<map>
#include <string>
#include <set>
#include <stack>
#include <queue>
#include <bitset>
using namespace std;

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


#define N   12

char g_page[N] = {};
int g_target = 0;
int g_min = INT_MAX;
int g_mway = 0;
short g_flag[1000000] = {};

int getNum(int iSt, int iLen, const char *inSz)
{
	char szInt[N];
	memset(szInt, 0, sizeof(szInt));

	for(int i = iSt; i < iSt+iLen; i++)
	{
		szInt[i-iSt] = inSz[i];
	}

	return atoi(szInt);
}

int getSub(int iSt, const char *inSz, char *outSz)
{
	for(int i = iSt; inSz[i]; i++)
	{
		outSz[i-iSt] = inSz[i];
	}

	return atoi(outSz);
}

void dfs(const char *szInt, int iSum, int iCen) 
{
	int iLen = strlen(szInt);

	for(int i = 1; i <= iLen; i++)
	{
		int iTemp = getNum(0, i, szInt);

		if(iSum+iTemp > g_target)
		{
			continue;
		}

		char szTmep[N];
		memset(szTmep, 0, sizeof(szTmep));
		getSub(i, szInt, szTmep);

		if(i == iLen)
		{
			if(g_min >= abs(iSum+iTemp - g_target))
			{
				g_min = abs(iSum+iTemp - g_target);
				g_mway = iCen;

				g_flag[g_min]++;
				//printf("%d %d\n", iSum+iTemp, g_mway);
			}
			continue;
		}

		dfs(szTmep, iSum + iTemp, iCen*10+i);
	}
	
	return ;
}

void printWay()
{
	char szTemp[N];

	//itoa(g_mway, szTemp, 10); // 不是C标准库的函数

	sprintf(szTemp,"%d",g_mway);

	int iPos = 0;
	int iLen = strlen(szTemp);

	for(int i = 0; i < iLen && g_mway > 0; i++)
	{
		int iTemp = int(szTemp[i] - '0');

		while(iTemp--)
		{
			printf("%c", g_page[iPos++]);
		}

		printf(" ");
	}

	while(g_page[iPos])
	{
		printf("%c", g_page[iPos++]);
	}

	printf("\n");
}

int getMin()
{
	int iSum = 0;
	int iLen = strlen(g_page);

	for(int i = 0; i < iLen; i++)
	{
		iSum += int(g_page[i] - '0');
	}

	return iSum;
}

int main()
{
	//int take = ::GetTickCount();
    //freopen("out47.txt", "w", stdout);

	while(true)
	{
		scanf("%d %s", &g_target, g_page);

		if(0 == g_target)
		{
			break;
		}

		memset(g_flag, 0, sizeof(g_flag));
		g_min = INT_MAX;
		g_mway = 0;

		if(getMin() > g_target)
		{
			printf("error\n");
		}
		else
		{
			dfs(g_page, 0, 0);

			if(g_flag[g_min] > 1)
			{
				printf("rejected\n");
			}
			else
			{
				printf("%d ", g_target-g_min);
				printWay();
			}
		}
		
		//printf("g_min=%d g_mway=%d\n", g_target-g_min, g_mway);
	}
	//cout<<::GetTickCount() - take<<endl;
	return 0;
}


最短路径数 Dijkstra+dfs

寻找最短路径数 标准dijkstra和spfa解法见 《畅通工程续——Dijkstra模板》 本篇多一项要求,求同样cost的最短路径数目。我们用dfs深搜,见代码注释。...
  • abcjennifer
  • abcjennifer
  • 2014年02月18日 15:01
  • 6233

分支界限法(剪枝法)学习

分支限界法与回溯法 (1)求解目标:回溯法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出在某种意义下的最优解。 ...
  • u011846436
  • u011846436
  • 2014年08月14日 10:28
  • 1331

一看就懂的Alpha-Beta剪枝算法详解

看了很多帖子,都没这个帖子讲的清楚.Alpha-Beta剪枝搜索是棋类走子计算的首选算法,由于估值函数问题,不适用于围棋...
  • baixiaozhe
  • baixiaozhe
  • 2016年07月10日 17:49
  • 30384

POJ1416 Shredding Company ACM解题报告(DFS回溯+剪枝)

本渣渣明天C语言考试,今天有点亢奋,又来了一题,这题感觉比前一题难多了,不仅是字符串转化为数字,即使看了百度提醒的搜索树,还是参考了一些百度的代码。感觉道阻且长,我仍需努力。下面是题目翻译: 公司现在...
  • Miracle_ma
  • Miracle_ma
  • 2014年12月25日 20:54
  • 758

POJ 1416 && OpenJudge 1805 Shredding Company (DFS+剪枝)

1805:碎纸机 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 你现在负责设计一种新式的碎纸机。一般的碎纸机会把纸切成小片,变得难以阅读。而你设计的新式...
  • Loi_Meiko
  • Loi_Meiko
  • 2016年10月18日 17:33
  • 316

POJ3373-Changing Digits【DFS+强剪枝】

  • 2011年08月19日 00:44
  • 12KB
  • 下载

POJ 1416Shredding Company(简单搜索技巧和剪枝)

Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 595...
  • jklcl
  • jklcl
  • 2017年02月07日 10:22
  • 88

POJ 1416 Shredding Company [暴力搜索 简单剪枝]

题意和思路: 给定一个目标值,和一个待拆分数值。 拆分的过程其实就是在各个数字中间有状态0 1 0:有隔板 1:无隔板 所以最长6位数。所有暴力枚举的话也就2^5=32的时间复杂度。肯定能过...
  • wuyanyi
  • wuyanyi
  • 2012年06月21日 20:23
  • 1253

poj 1416 Shredding Company (应该是用dfs吧,但是想了一下午不知道怎么递归来做,所以暴力做了)

Shredding Company Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 5381   Accepted...
  • obsessiveness_GHL
  • obsessiveness_GHL
  • 2016年08月13日 19:56
  • 258

[POJ 1416]Shredding Company[DFS]

题目链接:[POJ 1416]Shredding Company[DFS] 题意分析: 给出数字a和字符串b。问:字符串b能否切割后,使得每个数字相加,和最接近a但不超过a,如果有多组解,输出"r...
  • CatGlory
  • CatGlory
  • 2016年04月08日 23:56
  • 286
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ1416 切割纸条(DFS+剪枝)
举报原因:
原因补充:

(最多只允许输入30个字)