結果
| 問題 |
No.5005 3-SAT
|
| ユーザー |
👑 terry_u16
|
| 提出日時 | 2022-04-29 15:48:56 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 1,959 ms / 2,000 ms |
| コード長 | 6,396 bytes |
| コンパイル時間 | 3,344 ms |
| 実行使用メモリ | 6,952 KB |
| スコア | 22,169 |
| 最終ジャッジ日時 | 2022-04-29 15:52:22 |
| 合計ジャッジ時間 | 204,896 ms |
|
ジャッジサーバーID (参考情報) |
judge11 / judge14 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 100 |
ソースコード
use std::time::Instant;
macro_rules! get {
($t:ty) => {
{
let mut line: String = String::new();
std::io::stdin().read_line(&mut line).unwrap();
line.trim().parse::<$t>().unwrap()
}
};
($($t:ty),*) => {
{
let mut line: String = String::new();
std::io::stdin().read_line(&mut line).unwrap();
let mut iter = line.split_whitespace();
(
$(iter.next().unwrap().parse::<$t>().unwrap(),)*
)
}
};
($t:ty; $n:expr) => {
(0..$n).map(|_|
get!($t)
).collect::<Vec<_>>()
};
($($t:ty),*; $n:expr) => {
(0..$n).map(|_|
get!($($t),*)
).collect::<Vec<_>>()
};
($t:ty ;;) => {
{
let mut line: String = String::new();
std::io::stdin().read_line(&mut line).unwrap();
line.split_whitespace()
.map(|t| t.parse::<$t>().unwrap())
.collect::<Vec<_>>()
}
};
($t:ty ;; $n:expr) => {
(0..$n).map(|_| get!($t ;;)).collect::<Vec<_>>()
};
}
#[allow(unused_macros)]
macro_rules! chmin {
($base:expr, $($cmps:expr),+ $(,)*) => {{
let cmp_min = min!($($cmps),+);
if $base > cmp_min {
$base = cmp_min;
true
} else {
false
}
}};
}
#[allow(unused_macros)]
macro_rules! chmax {
($base:expr, $($cmps:expr),+ $(,)*) => {{
let cmp_max = max!($($cmps),+);
if $base < cmp_max {
$base = cmp_max;
true
} else {
false
}
}};
}
#[allow(unused_macros)]
macro_rules! min {
($a:expr $(,)*) => {{
$a
}};
($a:expr, $b:expr $(,)*) => {{
std::cmp::min($a, $b)
}};
($a:expr, $($rest:expr),+ $(,)*) => {{
std::cmp::min($a, min!($($rest),+))
}};
}
#[allow(unused_macros)]
macro_rules! max {
($a:expr $(,)*) => {{
$a
}};
($a:expr, $b:expr $(,)*) => {{
std::cmp::max($a, $b)
}};
($a:expr, $($rest:expr),+ $(,)*) => {{
std::cmp::max($a, max!($($rest),+))
}};
}
#[allow(unused_macros)]
macro_rules! mat {
($e:expr; $d:expr) => { vec![$e; $d] };
($e:expr; $d:expr $(; $ds:expr)+) => { vec![mat![$e $(; $ds)*]; $d] };
}
#[derive(Debug, Clone, Copy)]
struct Requirement {
digit: usize,
value: usize,
}
#[derive(Debug, Clone)]
struct Choice {
requirements: [Requirement; 3],
}
#[derive(Debug, Clone)]
struct Input {
since: Instant,
choices: Vec<Choice>,
prefix_sum: Vec<Vec<Vec<i32>>>,
}
const CHOICES_COUNT: usize = 2048;
const DIGIT_LEN: usize = 256;
const TIME_LIMIT: f64 = 1.95;
fn main() {
let input = read_input();
let solution = solve(&input);
write_output(&solution);
}
fn read_input() -> Input {
let mut choices = vec![];
let mut prefix_sum = mat![0; DIGIT_LEN; 2; CHOICES_COUNT + 1];
for i in 0..CHOICES_COUNT {
let (a, b, c, p, q, r) = get!(usize, usize, usize, usize, usize, usize);
prefix_sum[a][p][i + 1] += 1;
prefix_sum[b][q][i + 1] += 1;
prefix_sum[c][r][i + 1] += 1;
let requirements = [
Requirement { digit: a, value: p },
Requirement { digit: b, value: q },
Requirement { digit: c, value: r },
];
let choice = Choice { requirements };
choices.push(choice);
}
// TODO: 重なるケースとか真面目に見た方がいいかも
for i in 0..DIGIT_LEN {
for flag in 0..=1 {
let prefix_sum = &mut prefix_sum[i][flag];
for j in 1..prefix_sum.len() {
prefix_sum[j] += prefix_sum[j - 1];
}
}
}
let since = Instant::now();
let input = Input {
since,
choices,
prefix_sum,
};
input
}
fn solve(input: &Input) -> Vec<usize> {
let mut counts = vec![0; DIGIT_LEN];
let mut solution = vec![0; DIGIT_LEN];
let mut best_solution = vec![0; DIGIT_LEN];
let mut best_score = 0;
let mut total_count = 0;
dfs(
input,
&mut solution,
&mut best_solution,
&mut best_score,
&mut counts,
&mut total_count,
0,
);
eprintln!("score: {}", best_score);
eprintln!("count: {}", total_count);
best_solution
}
fn dfs(
input: &Input,
solution: &mut Vec<usize>,
best_solution: &mut Vec<usize>,
best_score: &mut usize,
counts: &mut [usize],
total_count: &mut usize,
depth: usize,
) -> bool {
if *total_count % 1000 == 0 {
let elapsed = (Instant::now() - input.since).as_secs_f64();
if elapsed > TIME_LIMIT {
return false;
}
}
if chmax!(*best_score, depth) {
*best_solution = solution.clone();
}
if depth == CHOICES_COUNT {
return false;
}
// 良さそうなやつから探索
let mut future_counts = [0; 3];
let mut indices = [0, 1, 2];
let choice = &input.choices[depth];
for i in 0..3 {
let req = &choice.requirements[i];
let prefix_sum = &input.prefix_sum[req.digit][req.value ^ 1];
let future_count = prefix_sum[CHOICES_COUNT] - prefix_sum[depth];
future_counts[i] = future_count;
}
indices.sort_unstable_by_key(|i| future_counts[*i]);
for index in indices.iter() {
let req = &choice.requirements[*index];
if counts[req.digit] == 0 || solution[req.digit] == req.value {
counts[req.digit] += 1;
*total_count += 1;
solution[req.digit] = req.value;
let in_time = dfs(
input,
solution,
best_solution,
best_score,
counts,
total_count,
depth + 1,
);
if !in_time {
return false;
}
counts[req.digit] -= 1;
}
}
return true;
}
fn write_output(solution: &[usize]) {
let mut result = String::new();
for v in solution.iter().rev() {
if *v == 0 {
result.push('0');
} else {
result.push('1');
}
}
println!("{}", result);
}
terry_u16