校內訓練 20161113

T1 Chocolate

給你一個nm 的矩陣,每個格子內都有一個權值aij 。問你是否可以將做k1 次分割,每次拿出一個矩陣,將它沿水平或豎直方向分成兩塊矩形。分割完成後一共有k ,如果可以分割,輸出“Yes”,反之“No”。
硬生生加了一點代碼量的題,前綴和+記憶化
#include <bits/stdc++.h>
#define rep( i , l , r ) for( int i = (l) ; i <= (r) ; ++i )
#define per( i , r , l ) for( int i = (r) ; i >= (l) ; --i )
#define erep( i , u ) for( int i = head[(u)] ; ~i ; i = e[i].nxt )
using namespace std;
void FileInOut(){
     freopen("chocolate.in" , "r" , stdin);
     freopen("chocolate.out" , "w" , stdout);
}
inline int _read(){
    int x = 0 , f = 1;
    char ch = getchar();
    while( !isdigit(ch) ) { if( ch == '-' ) f = -1 ; ch = getchar(); }
    while( isdigit(ch) ){
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
const int maxn = 30 + 5;
int a[maxn][maxn] , s[maxn][maxn] , aver = 0;
int dp[maxn][maxn][maxn][maxn];
int ck( int x1 , int y1 , int x2 , int y2 ){
    if( dp[x1][y1][x2][y2] != -1 ) return dp[x1][y1][x2][y2];
    int cur = s[x2][y2] - s[x2][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1];
    if( cur == aver ) return dp[x1][y1][x2][y2] = 1;
    if( cur % aver != 0 ) return dp[x1][y1][x2][y2] = 0;
    else{
        bool flg = 0;
        rep( x , x1 , x2 - 1 ){
            int res = s[x][y2] - s[x][y1 - 1] - s[x1 - 1][y2] + s[x1 - 1][y1 - 1];
            if( res % aver != 0 ) continue;
            flg |= ( ck( x1 , y1 , x , y2 ) && ck( x + 1 , y1 , x2 , y2 ) );             
        }
        if( flg ) return dp[x1][y1][x2][y2] = 1;
        rep( y , y1 , y2 - 1 ){
            int res = s[x2][y] - s[x1 - 1][y] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1];
            if( res % aver != 0 ) continue;
            flg |= ( ck( x1 , y + 1 , x2 , y2 ) && ck( x1 , y1 , x2 , y ) );
        }
        return dp[x1][y1][x2][y2] = flg;
    }
}
void solve(){
    memset( s , 0 , sizeof s );
    int N = _read() , M = _read() , K = _read();
    rep( i , 1 , N )
        rep( j , 1 , M ){
            a[i][j] = _read();
            s[i][j] = a[i][j] + s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
        }
    if( s[N][M] % K != 0 ) { puts("NO"); return; }
    else{
        memset( dp , -1 , sizeof dp );
        aver = s[N][M] / K;
        if( ck( 1 , 1 , N , M ) ) puts("YES");
        else puts("NO");
    }
}
int main(){
    FileInOut();
    int T = _read();
    while( T-- ){ solve(); }
    return 0;
}

T2 Course

送分題
 #include <bits/stdc++.h>
#define rep( i , l , r ) for( int i = (l) ; i <= (r) ; ++i )
#define per( i , r , l ) for( int i = (r) ; i >= (l) ; --i )
#define erep( i , u ) for( int i = head[(u)] ; ~i ; i = e[i].nxt )
using namespace std;
void FileInOut(){
     freopen("course.in" , "r" , stdin);
     freopen("course.out" , "w" , stdout);
}
const int maxn = 100000 + 5;
typedef long long ll;
char s[maxn];
int cnt[30 + 5];
ll C( ll n , ll m ){
    ll res = 1;
    for( ll i = 1ll ; i <= m ; ++i )
        res = res * (n - i + 1ll) / i;
    return res;
}
int main(){
    FileInOut();
    int N , M , k = 0;
    scanf("%s\n%d" , s , &M);
    N = strlen(s);
    rep( i , 0 , N - 1 ) cnt[s[i] - 'a']++;
    sort( cnt , cnt + 26 , greater<int>() );
    int val = cnt[M - 1] , val_cnt = 0 , s = 0;
    rep( i , 0 , 25 )
        if( cnt[i] == val ) ++val_cnt;
    rep( i , 0 , M - 1 )
        if( cnt[i] == val ) ++k;
    rep( i , 0 , M - 1 ) s += cnt[i];
    cout << s << " " << C( (ll)val_cnt , (ll)k ) << endl;
    return 0;
}

T3 Prime

發現一個非常精妙的結論,比33 大的數,不能影響到後面的數,所以可以在33 內進行Bruteforce ,在33 以外進行貪心,這樣複雜度是2131000 .
發佈了48 篇原創文章 · 獲贊 3 · 訪問量 4053
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章