sv pack 1.

收录非传统题

1. qoj364/JOISC2017 - Broken Device

考虑每三位一组,那么若三位都可行存 \(2\) 位,三位有两位可行存 \(1\) 位即可。

考虑如下映射:

\[\begin{aligned} 0&\to 010\\ 1&\to100,011\\ 00&\to101\\ 01&\to111\\ 10&\to001\\ 11&\to110\\ \end{aligned} \]

那么唯一的问题变成了 \(\texttt{oxo}\)(即最中间一位坏掉)不能表示 \(0\)。但是这一位可以表示 \(00\)\(10\)!于是解决了问题。

点击查看代码
//qoj364

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
// #include "Annalib.h"

int p[60], tmp[160];

void Set(int x, int i){
    putchar(i+'0');
    tmp[x] = i;
}

int ban[160];
void Anna(int N, ll X, int K, int P[]){
    memset(ban, 0, sizeof(ban));
    for(int i = 0; i < K; ++ i){
        ban[P[i]] = 1;
    }
    int cnt = 0;
    for(int i = 0; i < 150; i += 3){
        if(!ban[i] && !ban[i+1] && !ban[i+2]){
            // puts("1234");
            int p = X % 4; X /= 4; cnt += 2;
            cerr << -p << ' ';
            if(p == 0){ Set(i, 1); Set(i+1, 0); Set(i+2, 1); }
            if(p == 1){ Set(i, 1); Set(i+1, 1); Set(i+2, 1); }
            if(p == 2){ Set(i, 0); Set(i+1, 0); Set(i+2, 1); }
            if(p == 3){ Set(i, 1); Set(i+1, 1); Set(i+2, 0); }
        } else if(!ban[i] && !ban[i+1]){
            // puts("1234");
            int p = X % 2; X /= 2; ++ cnt;
            cerr << p << ' ';
            if(p == 0){ Set(i, 0); Set(i+1, 1); Set(i+2, 0); }
            if(p == 1){ Set(i, 1); Set(i+1, 0); Set(i+2, 0); }
        } else if(!ban[i] && !ban[i+2]){
            // puts("1234");
            int p = X % 2;
            if(p){
                p = X % 2; X /= 2; ++ cnt;
            cerr << p << ' ';
                Set(i, 1); Set(i+1, 0); Set(i+2, 0);
            } else {
                p = X % 4; X /= 4; ++ cnt;
            cerr << -p << ' ';
                if(p == 0){ Set(i, 1); Set(i+1, 0); Set(i+2, 1); }
                if(p == 2){ Set(i, 0); Set(i+1, 0); Set(i+2, 1); }
            }
        } else if(!ban[i+1] && !ban[i+2]){
            int p = X % 2; X /= 2; ++ cnt;
            cerr << p << ' ';
            if(p == 0){ Set(i, 0); Set(i+1, 1); Set(i+2, 0); }
            if(p == 1){ Set(i, 0); Set(i+1, 1); Set(i+2, 1); }
        } else {
            Set(i, 0); Set(i+1, 0); Set(i+2, 0);
        }
        cerr << '\n';
    }
    cerr << cnt << ' ' << X << '\n';
}

// #include <bits/stdc++.h>
// using namespace std;
// typedef long long ll;
// #include "Brunolib.h"

long long Bruno(int N, int A[]){
    ll ans = 0, bs = 1;
    for(int i = 0; i < 150; i += 3){
        int val = A[i] * 4 + A[i+1] * 2 + A[i+2];
        if(val == 1){ ans += bs * 2; bs <<= 2; }
        if(val == 2){ ans += bs * 0; bs <<= 1; }
        if(val == 3){ ans += bs * 1; bs <<= 1; }
        if(val == 4){ ans += bs * 1; bs <<= 1; }
        if(val == 5){ ans += bs * 0; bs <<= 2; }
        if(val == 6){ ans += bs * 3; bs <<= 2; }
        if(val == 7){ ans += bs * 1; bs <<= 2; }
    }
    cerr << ans << ' ' << bs << '\n';
    return ans;
}

int main(){
    for(int i = 1; i <= 40; ++ i){
        p[i] = i * 3 + rand() %3;
    }
    Anna(150, 235813068146480210ll, 40, p);
    for(int i = 1; i <= 40; ++ i){
        tmp[p[i]] = 0;
    }
    printf("%lld\n", Bruno(150, tmp));
}
posted @ 2024-10-16 20:43  KiharaTouma  阅读(1)  评论(0编辑  收藏  举报