题目描述
小马最近找到了一款打气球的游戏。
每一回合都会有 n个气球,每个气球都有对应的分值,第 i个气球的分值为ai。
这一回合内,会给小马两发子弹,但是由于小马的枪法不准,一发子弹最多只能打破一个气球,甚至小马可能一个气球都打不中。
现给出小马的得分规则:
-
若小马一只气球都没打中,记小马得0分。
-
若小马打中了第 i只气球,记小马得ai 分。
-
若小马打中了第 i只气球和第 j只气球(i<j),记小马得 ai|aj分。
(其中| 代表按位或,按位或的规则如下:
参加运算的两个数,按二进制位进行或运算,只要两个数中的一个为1,结果就为1。
即 0|0=0, 1|0=1, 0|1=1, 1|1=1。
例 2|4即 00000010|00000100=00000110,所以2|4=6
现在请你计算所有情况下小马的得分之和。
输入描述:
第一行,一个整数n,表示此回合的气球数量。
第二行,用空格分开的n 个整数,第i个整数为ai,表示每个气球对应的分值。
对于其中60% 的数据, 1≤n≤1000, 1≤ai≤100000
对于另外 40% 的数据, 1≤n≤50000, 1≤ai≤100000
输出描述
一行一个整数,代表所有情况下小马的得分之和。
分析
分为三种情况
1 小马哥两次都没有打中
两次都没打中的情况下 并不需要累加到得分之中。
2 小马哥打中一次
由于是一个回合,我们并不需要考虑是第一次打中而第二次没打中,还是第二次打中第一次没打中。
可以认为是个组合问题,没有顺序的
3 小马哥打中两次
代码
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
int n;
cin >> n;
vector<int> v1;
int value;
for (int i = 0; i < n; i++)
{
cin >> value;
v1.push_back(value);
}
long long ans = 0;
for (int i = 0; i < n; i++)
{
ans += v1[i]; //打中一次
for (int j = i + 1; j < n; j++)
{
ans += v1[i] | v1[j]; //打中两次
}
}
cout << ans << endl;
return 0;
}
需要注意的是
变量 ans 必须定义为 long long 型 ,如果定义为 int 类型就会报错