给出两个长度分别为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);//listmin = 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函数就是输入,没得说