B
あなたは買い物をしていて,商品リストからいくつかの商品を選んだ.そして今,その商品の価格を合計しようとしている.
ところで,とある集合の任意の部分集合を 2 進数を用いて表す方法が存在し,forループで全ての部分集合(組み合わせ)を列挙する際などに用いることができる.
n 個の商品があり, 商品0,商品1,..,商品n−1 があるとする.添字が0から始まることに注意せよ.
部分集合を表す 10 進整数を X とし,その 2 進 n 桁表現をbn−1bn−2…b1b0とする.b0 が最下位ビットで bn−1 が最上位ビットである.先頭の0 を許す表現であることに注意せよ.
そして,この整数 X の 2 進表現を用いて,ある部分集合を以下のように定義する.
b0=1 ならば集合は商品0 を含み,b0=0 ならば集合は商品 0 を含まない.
b1=1 ならば集合は商品1 を含み,b1=0 ならば集合は商品 1 を含まない.
...
bn−1=1 ならば集合は商品 n−1 を含み,bn−1=0 ならば集合は商品 n−1 を含まない.
例えば,n=4,X=5 のとき, b=0101 であり,部分集合は {商品0,商品2} である. 簡単にいえば,Xの 2 進表現において,k(0≦k≦n−1) 番目のビットが立っていれば k 番目のアイテムを含むということである.あるビットが立っているかどうかは,多くのプログラミング言語で容易に判定できるので,各自調べられたい.
あなたの仕事は,商品の数,それぞれの商品の価格,そして部分集合を表す 10 進整数 X が与えられるので,部分集合に含まれる商品の価格を合計することである.
※今回の問題には直接関係は無いが,部分集合を上記のように表現することで,大きさ n の集合の全ての部分集合(空集合を含む)を0 ~ 2n−1 の連続した整数で表現できるので,全列挙を行う際には応用するとよい.
いや問題文わかりにく、、
<< 左シフト演算子。
unsigned x=1u << 8;//1を8bit左シフトする。x=256
std::cout << "result:"<<x//標準出力にresult:256と出力
# include <iostream>
using namespace std;
int main() {
int n, X;
int a[21];
int ans = 0;
cin >> n >> X;
for (int i = 0; i < n; ++i)cin >> a[i];
for (int j = 0; j < n; ++j) {
if (X &(1 << j))ans += a[j];
}
cout << ans << endl;
return 0;
}
bitの使い方的な問題。おれもいうてちゃんとわかってない
C
# include<iostream>
# include<algorithm>
# include<vector>
# include<string>
# include<list>
# include<cmath>
# include<map>
using namespace std;
using ll = long long;
const int INF = 1e9;
# define rep(i,n)for(int i=0;i<n;++i)
# define p pair<int,int>
int main() {
int N;
cin >> N;
int ans = 0;
int imos[1000010];
for (int i = 0; i < 1000010; ++i) {
imos[i] = 0;
}
for (int i = 0; i < N; ++i) {
int a, b;
cin >> a >> b;
imos[a]++;
imos[b + 1]--;
}
for (int i = 0; i < 1000010; ++i) {
if (i > 0) {
imos[i] += imos[i - 1];
}
}
for (int i = 0; i < 1000010; ++i) {
ans = max(ans, imos[i]);
}
cout << ans << endl;
return 0;
}
いもす法