AtCoder Tenka1 Programmer Beginner Contest 解題報告
阿新 • • 發佈:2018-12-18
賽時寫了ABC,D實在沒啥思路,然後C又難調...然後就從寫完AB時的32名掉到了150+名
T_T
碼力不夠,思維不行,我還是AFO吧
A - Measure
sb模擬,奇數串倒著輸出偶數串正著輸出
#include <bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f #define il inline #define in1(a) a=read() #define in2(a,b) in1(a),in1(b) #define in3(a,b,c) in2(a,b),in1(c) #defineView Codein4(a,b,c,d) in2(a,b),in2(c,d) #define out(a) printf( "%d" , a ) #define outn(a) out(a),putchar('\n') #define I_int int inline I_int read() { I_int x = 0 , f = 1 ; char c = getchar() ; while( c < '0' || c > '9' ) { if( c == '-' ) f = -1 ; c = getchar() ; }while( c >= '0' && c <= '9' ) { x = (x << 1) + (x << 3) + c - 48 ; c = getchar() ; } return x * f ; } #undef I_int using namespace std ; #define N 100010 char s[ N ] ; int main() { scanf( "%s" , s + 1 ) ; int len = strlen( s+1 ) ;if( len == 2 ) puts( s + 1 ) ; else { for( int i = len ; i ; i -- ) putchar( s[ i ] ) ; } }
B - Exchange
還是模擬...按著題意的要求來就好,奇數一種情況偶數一種情況
然後一邊$+\frac{1}{2}$,一邊$-\frac{1}{2}$就好
#include <bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f #define il inline #define in1(a) a=read() #define in2(a,b) in1(a),in1(b) #define in3(a,b,c) in2(a,b),in1(c) #define in4(a,b,c,d) in2(a,b),in2(c,d) #define out(a) printf( "%d" , a ) #define outn(a) out(a),putchar('\n') #define I_int int inline I_int read() { I_int x = 0 , f = 1 ; char c = getchar() ; while( c < '0' || c > '9' ) { if( c == '-' ) f = -1 ; c = getchar() ; } while( c >= '0' && c <= '9' ) { x = (x << 1) + (x << 3) + c - 48 ; c = getchar() ; } return x * f ; } #undef I_int using namespace std ; #define N 100010 int a[ 3 ] , k ; int main() { in2( a[ 1 ] , a[ 0 ] ) ; in1( k ) ; for( int i = 1 ; i <= k ; i ++ ) { if( a[ i % 2 ] % 2 ) a[ i % 2 ] -- ; a[ ( i % 2 ) ^ 1 ] += a[ i % 2 ] / 2 ; a[ i % 2 ] -= a[ i % 2 ] / 2 ; } out( a[ 1 ] ) , putchar(' ') , outn( a[ 0 ] ) ; }View Code
C - Align
很噁心的分類討論
首先要知道一個結論,最中間的數一定是最大或者最小的,然後我們可以在旁邊依次填入最大/次大/最小/次小的數
對串的奇偶分開討論(取mid的不同)
然後對於中間填最大還是填最小也要分開討論
然後綜合幾種情況取個最優就行
寫的有點長,實際上應該不用這麼多程式碼的QAQ
#include <bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f #define il inline #define in1(a) a=read() #define in2(a,b) in1(a),in1(b) #define in3(a,b,c) in2(a,b),in1(c) #define in4(a,b,c,d) in2(a,b),in2(c,d) #define out(a) printf( "%d" , a ) #define outn(a) out(a),putchar('\n') #define I_int int inline I_int read() { I_int x = 0 , f = 1 ; char c = getchar() ; while( c < '0' || c > '9' ) { if( c == '-' ) f = -1 ; c = getchar() ; } while( c >= '0' && c <= '9' ) { x = (x << 1) + (x << 3) + c - 48 ; c = getchar() ; } return x * f ; } #undef I_int using namespace std ; #define N 100010 int n ; int b[ N ] ; int a[ N ] ; ll ans = 0 ; int main() { in1( n ) ; for( int i = 1 ; i <= n ; i ++ ) in1( a[ i ] ) ; sort( a+1 , a+n+1 ) ; int l = 1 , r = n , mid = ( l + r ) >> 1 ; if( n % 2 ) { b[ mid ] = a[ r -- ] ; for( int i = mid - 1 ; i ; i -- ) { if( ( mid - i ) % 2 ) b[ i ] = a[ l ++ ] , b[ mid + mid - i ] = a[ l ++ ] ; else b[ i ] = a[ r -- ] , b[ mid + mid - i ] = a[ r -- ] ; } ll sum = 0 ; for( int i = 2 ; i <= n ; i ++ ) sum += abs( b[ i ] - b[ i - 1 ] ) ; ll t = sum ; l = 1 , r = n ; b[ mid ] = a[ l ++ ] ; for( int i = mid - 1 ; i ; i -- ) { if( ( mid - i ) % 2 == 0 ) b[ i ] = a[ l ++ ] , b[ mid + mid - i ] = a[ l ++ ] ; else b[ i ] = a[ r -- ] , b[ mid + mid - i ] = a[ r -- ] ; } sum = 0 ; for( int i = 2 ; i <= n ; i ++ ) sum += abs( b[ i ] - b[ i - 1 ] ) ; printf( "%lld\n" , max( t , sum ) ) ; return 0 ; } b[ mid ] = a[ r -- ] ; b[ mid + 1 ] = a[ l ++ ] ; for( int i = mid - 1 ; i ; i -- ) { if( ( mid - i ) % 2 ) b[ i ] = a[ l ++ ] , b[ n - i + 1 ] = a[ r -- ] ; else b[ i ] = a[ r -- ] , b[ n - i + 1 ] = a[ l ++ ] ; } ll sum = 0 , t = 0 ; for( int i = 2 ; i <= n ; i ++ ) { sum += abs( b[ i ] - b[ i - 1 ] ) ; } t = sum ; l = 1 , r = n ; b[ mid + 1 ] = a[ r -- ] ; b[ mid ] = a[ l ++ ] ; for( int i = mid - 1 ; i ; i -- ) { if( ( mid - i ) % 2 == 0 ) b[ i ] = a[ l ++ ] , b[ n - i + 1 ] = a[ r -- ] ; else b[ i ] = a[ r -- ] , b[ n - i + 1 ] = a[ l ++ ] ; } sum = 0 ; for( int i = 2 ; i <= n ; i ++ ) { sum += abs( b[ i ] - b[ i - 1 ] ) ; } printf( "%lld\n" , max( sum , t ) ) ; }View Code
D - Crossing
寫這題之前一定要先讀懂題意
我比賽時一直讀錯題意,到結束時腦子裡想的還是錯誤的題意....然後就炸了
令k為所選子集的數量。
任何兩個子集的交集大小為1,並且為1,2,...,N中的任何一個元素也使用了兩次
對於選出來的子集的限制就是這樣的
我們不妨把這些子集抽象成點,交集抽象成邊,於是$1-n$這些元素就是邊的種類
那麼不難看出整個圖有$\frac{k(k-1)}{2}$條邊,並且邊的數目要等於n
於是可以枚舉出來這個k先,qzz大佬好像推了一個式子$O(1)$求出了這個k,不過我數學比較菜就直接枚舉了T_T
然後如果這個k列舉不出來就說明無解(一個比較玄學的地方,我從1列舉到n來判會WA掉第一個點,其他都沒問題,然後從1列舉到500就沒問題,不知道是怎麼回事)
然後來連邊
因為每個元素要溝通兩個子集
所以類似於完全圖那樣連邊就好
int x = 0 ; for( int i = 0 ; i < k ; i ++ ) { for( int j = i + 1 ; j < k ; j ++ ) { x ++ ; s[ i ].push_back( x ) ; s[ j ].push_back( x ) ; } }
然後就沒了
所以說這題的主要難度在於讀懂題意T_T
#include <bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f #define il inline #define in1(a) a=read() #define in2(a,b) in1(a),in1(b) #define in3(a,b,c) in2(a,b),in1(c) #define in4(a,b,c,d) in2(a,b),in2(c,d) #define out(a) printf( "%d" , a ) #define out_(a) printf( " %d" , a ) #define outn(a) out(a),putchar('\n') #define I_int int inline I_int read() { I_int x = 0 , f = 1 ; char c = getchar() ; while( c < '0' || c > '9' ) { if( c == '-' ) f = -1 ; c = getchar() ; } while( c >= '0' && c <= '9' ) { x = (x << 1) + (x << 3) + c - 48 ; c = getchar() ; } return x * f ; } #undef I_int using namespace std ; #define N 100010 int n , k ; vector<int>s[N]; int main() { in1( n ) ; k = -1 ; for( int i = 1 ; i < 500 ; i ++ ) if( i * ( i - 1 ) / 2 == n ) { k = i ; break ; } if( k == -1 ) { return puts("No"),0; } int x = 0 ; for( int i = 0 ; i < k ; i ++ ) { for( int j = i + 1 ; j < k ; j ++ ) { x ++ ; s[ i ].push_back( x ) ; s[ j ].push_back( x ) ; } } puts("Yes"); outn(k); for( int i = 0 ; i < k ; i ++ ) { out((int)s[i].size()); int len = s[ i ].size(); for( int j = 0 ; j < len ; j ++ ) { out_(s[i][j]); } putchar('\n'); } return 0 ; }View Code
還是太菜,還是要繼續努力啊QAQ