結果
| 問題 |
No.2910 単体ホモロジー入門
|
| コンテスト | |
| ユーザー |
👑 |
| 提出日時 | 2023-01-22 11:21:32 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 2 ms / 2,000 ms |
| コード長 | 3,072 bytes |
| コンパイル時間 | 3,319 ms |
| コンパイル使用メモリ | 68,000 KB |
| 最終ジャッジ日時 | 2025-02-10 06:20:58 |
|
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 47 |
ソースコード
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdint.h>
#include <cassert>
using namespace std;
#define TYPE_OF( VAR ) remove_const<remove_reference<decltype( VAR )>::type >::type
#define UNTIE ios_base::sync_with_stdio( false ); cin.tie( nullptr )
#define CEXPR( LL , BOUND , VALUE ) constexpr const LL BOUND = VALUE
#define CIN( LL , A ) LL A; cin >> A
#define ASSERT( A , MIN , MAX ) assert( ( MIN ) <= A && A <= ( MAX ) )
#define CIN_ASSERT( A , MIN , MAX ) CIN( TYPE_OF( MAX ) , A ); ASSERT( A , MIN , MAX )
#define FOR( VAR , INITIAL , FINAL_PLUS_ONE ) for( TYPE_OF( FINAL_PLUS_ONE ) VAR = INITIAL ; VAR < FINAL_PLUS_ONE ; VAR ++ )
#define REPEAT( HOW_MANY_TIMES ) FOR( VARIABLE_FOR_REPEAT , 0 , HOW_MANY_TIMES )
#define QUIT return 0
#define COUT( ANSWER ) cout << ( ANSWER ) << "\n";
#define RETURN( ANSWER ) COUT( ANSWER ); QUIT
template <int L>
void IncrementPath( int ( &path )[L] )
{
constexpr const int L_m = L - 1;
FOR( k , 0 , L_m ){
int& path_k = path[k];
if( ++path_k < path[k+1] ){
return;
}
path_k = 0;
}
path[L_m]++;
return;
}
#define CHECK_LOOP( NUM , CHECK_VALID ) \
REPEAT( path_ ## NUM ## _bound ){ \
count = 0; \
FOR( n , 0 , N ){ \
vertex[n] = 0; \
} \
FOR( k , 0 , NUM ){ \
int path_k = path[k]; \
int& vij0 = vertex[ij0[path_k]]; \
if( vij0 == 1 ){ \
count++; \
} \
vij0++; \
int& vij1 = vertex[ij1[path_k]]; \
if( vij1 == 1 ){ \
count++; \
} \
vij1++; \
} \
if( count == NUM ){ \
CHECK_VALID; \
} \
IncrementPath( path ); \
} \
\
#define CHECK_VALID_FOUR RETURN( "Yes" )
#define CHECK_VALID_THREE FOR( i , 0 , N ){ if( vertex[i] != vertex_exception[i] ){ RETURN( "Yes" ); } }
#define CHECK_LOOP_FOUR CHECK_LOOP( four , CHECK_VALID_FOUR )
#define CHECK_LOOP_THREE CHECK_LOOP( three , CHECK_VALID_THREE )
int main()
{
UNTIE;
CEXPR( int , bound_N , 4 );
CIN_ASSERT( N , 1 , bound_N );
if( N < 3 ){
RETURN( "No" );
}
CEXPR( int , bound_M , ( bound_N * ( bound_N - 1 ) ) / 2 );
CIN_ASSERT( M , 0 , bound_M );
if( M < 3 ){
RETURN( "No" );
}
int ij0[bound_M];
int ij1[bound_M];
FOR( m , 0 , M ){
CIN( int , ij0m );
CIN( int , ij1m );
assert( 0 <= ij0m && ij0m < ij1m && ij1m < N );
FOR( k , 0 , m ){
assert( ij0[k] != ij0m || ij1[k] != ij1m );
}
ij0[m] = ij0m;
ij1[m] = ij1m;
}
int count;
int vertex[bound_N];
if( N == 4 ){
CEXPR( int , four , 4 );
int path[four] = { 0 , 1 , 2 , 3 };
int path_four_bound = ( ( ( ( ( M * ( M - 1 ) ) / 2 ) * ( M - 2 ) ) / 3 ) * ( M - 3 ) ) / 4;
CHECK_LOOP_FOUR;
}
int vertex_exception[bound_N] = {};
CEXPR( int , three , 3 );
REPEAT( three ){
CIN_ASSERT( i_v , 0 , N - 1 );
vertex_exception[i_v] += 2;
}
int path[three] = { 0 , 1 , 2 };
int path_three_bound = ( ( ( M * ( M - 1 ) ) / 2 ) * ( M - 2 ) ) / 3;
CHECK_LOOP_THREE;
RETURN( "No" );
}