T1 Chocolate
给你一个
n∗m
的矩阵,每个格子内都有一个权值
aij
。问你是否可以将做
k−1
次分割,每次拿出一个矩阵,将它沿水平或竖直方向分成两块矩形。分割完成后一共有
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
以外进行贪心,这样复杂度是
213∗1000
.
#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;
}
#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;
}