【枚举】工件

1、工件(jia.pas)

 

【题目描述】

Mr.L很多工件,最常见的工件都是长条形的,但其顶端是凹凸不平的,即不同位置的高度不同。现在Mr.L有两个最常见的工件,他想将它们完全放入另一种罕见的可容纳高度不超过k的工件中,问该罕见的工件的最小长度。

 

【输入格式】

输入来自文件jia.in,包括三行。第一行包含一个不超过20的正整数k;接下来每行有一个长度不超过100的正整数串,其中的每个数都在1到9之间,表示该常见工件对应位置的高度。

 

【输出格式】

输出到文件jia.out,包括一个数字即罕见的工件的最小长度。如果无解则输出“Impossible”。

【样例输入1】

4

2213

231223

 

【样例输出1】

7

 

【样例输入2】

1

2112

122111

 

【样例输出2】

Impossible


这道题要读懂题意,因为一个工件是可以旋转180°的。


首先判断工件是否有一个位置大于高度,是则无解。


固定这个工件,移动那个。然后再固定那个工件,移动这个工件,统一向右移动,避免了负下标。

必定第一次成功就是最小值,因为一开始重合地最多,随着移动而重合部分越来越少。


平移完没有找到,至少两个刚好错开可以有解,两个长度相加。


#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
using std::reverse;
using std::max;
using std::min;

long getint()
{
	long rs=0;bool sgn=1;char tmp;
	do tmp = getchar();
	while (!isdigit(tmp)&&tmp!='-');
	if (tmp=='-'){tmp=getchar();sgn=0;}
	do rs=(rs<<3)+(rs<<1)+tmp-'0';
	while (isdigit(tmp=getchar()));
	return sgn?rs:-rs;
}

char a[500];
char b[500];
long la,lb;

int main()
{
	freopen("jia.in","r",stdin);
	freopen("jia.out","w",stdout);

	long k = getint();
	scanf("%s",a+1);
	scanf("%s",b+1);
	la = strlen(a+1);
	lb = strlen(b+1);

	for (long i=1;i<la+1;i++)
	{
		a[i] -= '0';
		if (a[i] > k)
		{
			printf("Impossible");
			return 0;
		}
	}
	for (long i=1;i<lb+1;i++)
	{
		b[i] -= '0';
		if (b[i] > k)
		{
			printf("Impossible");
			return 0;
		}
	}

	long ans = 0x3f3f3f3f;

	for (long i=1;i<la+1;i++)
	{
		bool ok = true;
		for (long j=1;j<lb+1;j++)
		{
			if (a[i+j-1] + b[j] > k)
			{
				ok = false;
				break;
			}
		}
		if (ok)
		{
			ans = max(la,i+lb-1);
			break;
		}
	}
	for (long i=1;i<lb+1;i++)
	{
		bool ok = true;
		for (long j=1;j<la+1;j++)
		{
			if (b[i+j-1] + a[j] > k)
			{
				ok = false;
				break;
			}
		}
		if (ok)
		{
			ans = min(ans,max(lb,i+la-1));
			break;
		}
	}

	reverse(b+1,b+1+lb);

	for (long i=1;i<la+1;i++)
	{
		bool ok = true;
		for (long j=1;j<lb+1;j++)
		{
			if (a[i+j-1] + b[j] > k)
			{
				ok = false;
				break;
			}
		}
		if (ok)
		{
			ans = min(ans,max(la,i+lb-1));
			break;
		}
	}
	for (long i=1;i<lb+1;i++)
	{
		bool ok = true;
		for (long j=1;j<la+1;j++)
		{
			if (b[i+j-1] + a[j] > k)
			{
				ok = false;
				break;
			}
		}
		if (ok)
		{
			ans = min(ans,max(lb,i+la-1));
			break;
		}
	}

	if (ans == 0x3f3f3f3f)
		printf("%ld",la+lb);
	else
		printf("%ld",ans);
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值