2進数を使って、最小値を求めたいです。
Posted: 2015年4月03日(金) 14:50
こんにちは。
今回、POJというサイトの問題を解いていて、どうしても解法が分からずいろいろ調べていたところ、ビット演算子、bitsetを用いた解法を見つけ、どうにかして理解したく、ここにて質問させていただきます。
問題:http://poj.org/problem?id=2718
問題の概要:0~9までの最大の長さ10、最小の長さ2の数列があって、それを順番は自由でよいので、二つに分割し、それの最小値の絶対値を求める問題です。
2進数を用いた解法を使っていたコードです。
(http://www.hankcs.com/program/poj-2718- ... swers.html さんより引用)
このなかで、どうしてもわからない所は
です。ビット演算子の部分は理解できたのですが、 bitset<10> used = static_cast<bitset<10>>(permute);のところで二進数に変換し、usedに格納しているところまではどうにかわかりました。しかし、次のfor分で、uesdが0,1のどちらかで、s1、s2どっちに入れるか決めているところで、どうしてこのような解法が出てきたのかわかりません。
どなたか教えていただけないでしょうか?
今回、POJというサイトの問題を解いていて、どうしても解法が分からずいろいろ調べていたところ、ビット演算子、bitsetを用いた解法を見つけ、どうにかして理解したく、ここにて質問させていただきます。
問題:http://poj.org/problem?id=2718
問題の概要:0~9までの最大の長さ10、最小の長さ2の数列があって、それを順番は自由でよいので、二つに分割し、それの最小値の絶対値を求める問題です。
2進数を用いた解法を使っていたコードです。
#ifndef ONLINE_JUDGE
#pragma warning(disable : 4996)
#endif
#include <iostream>
#include <string>
#include <algorithm>
#include <bitset>
using namespace std;
///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int n;
cin >> n;
cin.ignore();
while (n--)
{
string all;
getline(cin, all);
all.erase(remove(all.begin(), all.end(), ' '), all.end());
int length = all.size();
int cut = length / 2;
int permute = 1 << length;
int result = 0x3F3F3F3F;
do
{
bitset<10> used = static_cast<bitset<10>>(permute);
string s1, s2;
for (int i = 0; i < length; ++i)
{
if (used[i])
{
s1 += all[i];
}
else
{
s2 += all[i];
}
}
if (s1.size() != cut)
{
continue;
}
if (s1[0] == '0' && s1.size() > 1)
{
continue;
}
// s1 s2 已经被切割出来了
// 穷举它们
do
{
int n1 = atoi(s1.c_str());
do
{
if (s2[0] == '0' && s2.size() > 1)
{
continue;
}
int n2 = atoi(s2.c_str());
int dif = abs(n1 - n2);
//cout << s1 << ' ' << s2 << " dif " << dif << " result: " << result << endl;
if (dif < result)
{
result = dif;
}
} while (next_permutation(s2.begin(), s2.end()));
} while (next_permutation(s1.begin(), s1.end()));
} while (--permute);
cout << result << endl;
}
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
system("out.txt");
#endif
return 0;
}
(http://www.hankcs.com/program/poj-2718- ... swers.html さんより引用)
このなかで、どうしてもわからない所は
int length = all.size();
int cut = length / 2;
int permute = 1 << length;
int result = 0x3F3F3F3F;
do
{
bitset<10> used = static_cast<bitset<10>>(permute);
string s1, s2;
for (int i = 0; i < length; ++i)
{
if (used[i])
{
s1 += all[i];
}
else
{
s2 += all[i];
}
}
どなたか教えていただけないでしょうか?