0w1

CFR 389 D. Fox and Minimal path ( Binary Enumeration )

Problem - D - Codeforces

題意:
給 K,求一個無向圖鄰接矩陣,使得節點 1 到節點 2 的最短路徑恰有 K 個。

資料規模:
1 ≤ K ≤ 1e9
輸出的圖的節點數 ≤ 1000

解法:
考慮二進制枚舉,需要 *2 就往右連一個菱形,需要 +1 就從節點 1 連到當前的終點。

#include <bits/stdc++.h>
using namespace std;

const int MAXN = 1000;

int K;
int G[ MAXN ][ MAXN ];

signed main(){
  ios::sync_with_stdio( 0 );
  cin >> K;
  if( K == 1 ){
    cout << 2 << endl;
    cout << "NY" << endl;
    cout << "YN" << endl;
    exit( 0 );
  }
  queue< int > que;
  for( int i = 2; i < MAXN; ++i ){
    que.emplace( i );
  }
  int f = 0;
  for( int i = 31 - __builtin_clz( K ) - 1, len = 2 ; i >= 0; len += 2, --i ){
    int u = que.front(); que.pop();
    int d = que.front(); que.pop();
    int m = 1; if( i > 0 ) m = que.front(), que.pop();
    G[ f ][ u ] = G[ u ][ f ] = 1;
    G[ f ][ d ] = G[ d ][ f ] = 1;
    G[ u ][ m ] = G[ m ][ u ] = 1;
    G[ d ][ m ] = G[ m ][ d ] = 1;
    f = m;
    if( K >> i & 1 ){
      int p = 0;
      for( int j = 0; j < len - 1; ++j ){
        int nxt = que.front(); que.pop();
        G[ p ][ nxt ] = G[ nxt ][ p ] = 1;
        p = nxt;
      }
      G[ p ][ f ] = G[ f ][ p ] = 1;
    }
  }
  cout << MAXN << endl;
  for( int i = 0; i < MAXN; ++i ){
    for( int j = 0; j < MAXN; ++j ){
      cout << "NY"[ G[ i ][ j ] ];
    }
    cout << "\n";
  }
  return 0;
}