結果
| 問題 |
No.5005 3-SAT
|
| ユーザー |
👑 terry_u16
|
| 提出日時 | 2022-04-29 15:28:23 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 1,952 ms / 2,000 ms |
| コード長 | 6,442 bytes |
| コンパイル時間 | 1,138 ms |
| 実行使用メモリ | 2,212 KB |
| スコア | 38,251 |
| 最終ジャッジ日時 | 2022-04-29 15:31:47 |
| 合計ジャッジ時間 | 202,873 ms |
|
ジャッジサーバーID (参考情報) |
judge14 / judge12 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| 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>,
}
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 counts = vec![0; DIGIT_LEN];
for _ in 0..CHOICES_COUNT {
let (a, b, c, p, q, r) = get!(usize, usize, usize, usize, usize, usize);
counts[a] += 1;
counts[b] += 1;
counts[c] += 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 choice in choices.iter_mut() {
choice
.requirements
.sort_unstable_by(|r0, r1| counts[r0.digit].cmp(&counts[r1.digit]));
}
let since = Instant::now();
let input = Input { since, choices };
input
}
fn solve(input: &Input) -> Vec<usize> {
solve_rand(input)
}
fn solve_rand(input: &Input) -> Vec<usize> {
let mut best_solution = vec![0; DIGIT_LEN];
let mut best_score = 0;
let mut solution = vec![0; DIGIT_LEN];
let mut counts = vec![0; DIGIT_LEN];
let mut rng = Xorshift::new();
let mut valid_choices = vec![];
'main: while (Instant::now() - input.since).as_secs_f64() < TIME_LIMIT {
solution.fill(0);
counts.fill(0);
for (i, choice) in input.choices.iter().enumerate() {
valid_choices.clear();
for req in choice.requirements.iter() {
if counts[req.digit] == 0 || solution[req.digit] == req.value {
valid_choices.push(req);
}
}
if valid_choices.len() == 0 {
if chmax!(best_score, i) {
best_solution = solution.clone();
}
continue 'main;
}
let index = rng.rand(valid_choices.len());
let choice = valid_choices[index];
solution[choice.digit] = choice.value;
counts[choice.digit] += 1;
}
best_score = input.choices.len();
best_solution = solution.clone();
}
eprintln!("score: {}", best_score);
best_solution
}
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);
}
#[derive(Debug)]
#[allow(dead_code)]
pub struct Xorshift {
seed: usize,
}
impl Xorshift {
#[allow(dead_code)]
pub fn new() -> Xorshift {
Xorshift {
seed: 0xf0fb588ca2196dac,
}
}
#[allow(dead_code)]
pub fn with_seed(seed: usize) -> Xorshift {
Xorshift { seed: seed }
}
#[inline]
#[allow(dead_code)]
pub fn next(&mut self) -> usize {
self.seed = self.seed ^ (self.seed << 13);
self.seed = self.seed ^ (self.seed >> 7);
self.seed = self.seed ^ (self.seed << 17);
self.seed
}
#[inline]
#[allow(dead_code)]
pub fn rand(&mut self, m: usize) -> usize {
self.next() % m
}
#[inline]
#[allow(dead_code)]
// 0.0 ~ 1.0
pub fn randf(&mut self) -> f64 {
use std::mem;
const UPPER_MASK: usize = 0x3FF0000000000000;
const LOWER_MASK: usize = 0xFFFFFFFFFFFFF;
let tmp = UPPER_MASK | (self.next() & LOWER_MASK);
let result: f64 = unsafe { mem::transmute(tmp) };
result - 1.0
}
}
terry_u16