我有这个问题:
你有n个问题。你估计了第i个的难度 作为整数ci。现在你想为比赛准备一个问题集, 使用你所做的一些问题。
比赛的问题集必须包含至少两个问题。 你认为比赛的问题总难度 必须至少为l且至多为r。另外,你认为差异 在最容易和最难选择的困难之间 问题必须至少是x。
找出为比赛选择问题集的方法数量。
输入第一行包含四个整数n,l,r,x(1≤n≤15, 1≤l≤r≤109,1≤x≤106) - 您遇到的问题数量, 问题集的总难度的最小值和最大值 最困难的问题之间的最小差异 包装和最简单的包装。
第二行包含n个整数c1,c2,...,cn(1≤ci≤106) - 每个问题的难度。
输出打印选择合适的问题集的方式数 比赛。
我试图解决它但不幸的是我做不到。我让一位朋友给我一个想法,他为我解决了这个问题,但我不明白:
代码:
#include <stdio.h>
int a[25], l, r, x, i, j, n, ans;
int main(){
scanf("%d %d %d %d", &n, &l, &r, &x);
for(i=0; i<n; i++) scanf("%d", &a[i]);
for(i=0; i<(1<<n); i++){
int s = 0;
int max = 0, min = 1e9;
for(j=0; j<n; j++){
if((i>>j)&1){
if(a[j] > max) max = a[j];
if(min > a[j]) min = a[j];
s += a[j];
}
}
if(l <= s && s <= r && max-min >= x) ans++;
}
printf("%d", ans);
return 0;
}
如果他只有n个元素,他为什么要通过那个数组直到i<(1<<n)
?
为什么他这样做:if((i>>j)&1)
?
我知道1<<n
相当于乘以2的幂,而1>>n
相当于整数除以2 ^ n,但这里没有任何意义。
答案 0 :(得分:3)
您可能遇到任何问题,并且每个问题都可以包含在问题集中或从问题集中排除。这意味着每个问题都有2个选项,因此对于n个问题,有2 ^ n个选项可用于创建可能的问题集。
使用行 <div>
<div ng-bind-html="betLoader ? '<span class="spinner"></span>': 'Win'"><div class="spinner"></div></span>
<div ng-show="!betLoader">Win</div>
</div>
迭代所有这些可能的问题集,每个问题集由0到2 ^ n - 1之间的整数标识。接下来,我们需要确定哪些问题属于某个问题集,我们有一个表示它的整数。
为此,我们采用该整数的二进制表示。它将具有for(i=0; i<(1<<n); i++)
位,并且可以说每个位对应一个问题:如果它是1,则包含问题,否则不包括。这就是行n
正在做的事情:它检查整数if((i>>j)&1)
内的位置j
中的位是否等于1,这意味着包含相应的问题。
其余部分更容易:从所有包含的问题中,您可以计算最小值,最大值和总和。然后,检查总和i
是否在有效范围内,以及最大值和最小值之间的差值是否至少为x。