给出两个长度分别为n1,n2(n1 + n2 <=32)且每列高度只为1或2的长条(保证高度为1的地方水平上一致)。需要将它们放入一个高度为3的容器长度,问能够容纳它们的最短容器长度
用手画的
本来是n1,n2 <= 100的,但是我想用一下按位运算符,就稍微改了一下题目
也可以数组模拟,这样可以满足原本的条件
输入格式:
第一行为两个整数,代表n1,n2
第二行有n1个数,为1或者2,代表列高
第三行有n2个数,为1或者2,代表列高
输出格式:
一个整数,代表最短容器长度
(注意:输入时长条的最下层是填满的,即如果要组装,需要将其中一个长条反转。且长条可以左右翻转(那前一句就没影响了,反正都要试一下))
代码如下:
#include<stdio.h>
int input(int length);
int roll(int l, int length);
int getmin(int l1, int l2, int n1, int n2);
int main(void)
{
int n1, n2, min = 0, tmp;
scanf("%d%d", &n1, &n2);
int l1 = input(n1), l2 = input(n2);//list
min = getmin(l1, l2, n1, n2);
l1 = roll(l1, n1);
tmp = getmin(l1, l2, n1, n2);
min = (tmp < min) ? tmp : min;
l2 = roll(l2, n2);
tmp = getmin(l1, l2, n1, n2);
min = (tmp < min) ? tmp : min;
l1 = roll(l1, n1);
tmp = getmin(l1, l2, n1, n2);
min = (tmp < min) ? tmp : min;
printf("%d", min);
return 0;
}
int input(int length)
{
int tmp = 0;
for(int i = 0, j; i < length; i++)
{
scanf("%d", &j);
tmp |= --j;
tmp <<= 1;
}
return tmp >> 1;
}
int roll(int l, int length)
{
int i = 1, j = 1;
for(int x = 1; x < length; x++)
j <<= 1;
for(; i < j; i <<= 1, j >>= 1)
{
int a = i & l, b = j & l;
if(a) l |= j;
else if(b) l -= b;
if(b) l |= i;
else if(a) l -= i;
}
return l;
}//将l上的二进制数翻转
int getmin(int l1, int l2, int n1, int n2)
{
for(int i = 0; i < n2; i++, l1 <<= 1)
if((l1 & l2) == 0)
return (n1 + i > n2) ? n1 + i : n2;
return n1 + n2;
}
roll函数是用来翻转“数组”的
getmin函数是用来得到这两个长条摆放情况的时候的最小容器长度的
input函数就是输入,没得说