1. 程式人生 > >2018.11.3 Nescafe18 T2 太鼓達人

2018.11.3 Nescafe18 T2 太鼓達人

題目

背景

七夕祭上,Vani 牽著 cl 的手,在明亮的燈光和歡樂的氣氛中
愉快地穿行。這時,在前面忽然出現了一臺太鼓達人機臺,而在機臺前坐著的是剛剛被精英隊伍成員 XLk、Poet_shy 和 lydrainbowcat拯救出來的的 applepi。看到兩人對太鼓達人產生了興趣,applepi果斷閃人,於是 cl 拿起鼓棒準備挑戰。然而即使是在普通難度下,cl 的路人本性也充分地暴露了出來。一曲終了,不但沒有過關,就連鼓都不靈了。Vani 十分過意不去,決定幫助工作人員修鼓。

題目描述

鼓的主要元件是 M 個圍成一圈的感測器。每個感測器都有開和關兩種工作狀態,分別用 1 和 0 表示。顯然,從不同的位置出發沿順時針方向連續檢查 K 個感測器可以得到 M 個長度為 K 的 01 串。Vani 知道這 M 個 01 串應該是互不相同的。而且鼓的設計很精密,M 會取到可能的最大值。現在 Vani 已經瞭解到了 K 的值,他希望你求出 M 的值,並給出字典序最小的感測器排布方案。

輸入格式

一個整數K。

輸出格式

一個整數 M 和一個二進位制串,由一個空格分隔。表示可能的最大的 M,以及字典序最小的排布方案,字元 0 表示關,1 表示開。你輸出的串的第一個字和最後一個字是相鄰的。

樣例輸入輸出

樣例輸入

3

樣例輸出

8 00010111

樣例說明

得到的 8 個 01 串分別是 000、001、010、101、011、111、110 和 100。注意前後是相鄰的。長度為 3 的二進位制串總共只有 8 種,所以 M = 8 一定是可能的最大值。

資料範圍及約定

對於全部測試點,2≤K≤11。

思路

做模擬賽的時候遇到一道自己以前做過的題orz。看到資料範圍想到打表(

基本就是個暴力……因為k很小,所以可以開一個vis陣列來記錄當前01串有沒有出現過。然後大力DFS就可以了。

程式碼

#include <iostream>
#include <cstdio>

using namespace std;

int k, n;
int ans[2050];
bool vis[2050];

bool dfs(int S, int x) {
    if(vis[S])
        return false;
    vis[S] = true;
    ans[x] = S & 1;
    if(x == n)
        return true;
    if(dfs(S << 1 & (n - 1), x + 1
)) return true; if(dfs((S << 1 | 1) & (n - 1), x + 1)) return true; vis[S] = false; return false; } int main() { freopen("taiko.in", "r", stdin); freopen("taiko.out", "w", stdout); scanf("%d", &k); n = 1 << k; dfs(n - 2, 1); printf("%d ", n); for(int i = 1; i <= n; ++i) printf("%d", ans[i]); printf("\n"); fclose(stdin); fclose(stdout); return 0; }