题意:给定一个w*h的矩形和一个数n,每次可以沿w一分为二,也可以沿h一分为二,前提是长度为偶数,问最后分成的块能否大于等于n
思路:将w和h一直分,分到不能分为止,最后乘起来为最后的块数,再与n比较即可
int main ( )
{
int t;
cin >> t;
while ( t-- ) {
int w, h, n;
cin >> w >> h >> n;
int c1 = 1 ;
while ( w% 2 == 0 ) {
w / = 2 ;
c1 * = 2 ;
}
int c2 = 1 ;
while ( h% 2 == 0 ) {
h / = 2 ;
c2 * = 2 ;
}
int cnt = c1* c2;
if ( cnt>= n) {
cout << "YES" << endl;
} else {
cout << "NO" << endl;
}
}
return 0 ;
}
题意:给定n个数,每个数的值为1或者2,问是否能将这些分成和相等的两堆
思路:特判两种情况即可,一种是和为奇数的情况,另一种是个数为奇数,并且没有1的存在,这两种情况为NO,其他均为YES
int s[ 110 ] ;
int main ( )
{
int t;
cin >> t;
while ( t-- ) {
int n;
cin >> n;
int sum = 0 ;
int cnt = 0 ;
for ( int i = 1 ; i <= n; i++ ) {
cin >> s[ i] ;
sum + = s[ i] ;
if ( s[ i] == 1 ) cnt++ ;
}
if ( sum% 2 == 1 || ( cnt== 0 && n% 2 == 1 ) ) {
cout << "NO" << endl;
} else {
cout << "YES" << endl;
}
}
return 0 ;
}
题意:给定n个数字的序列,每次选一个位置开始,其得分为每次所在位置的数值之后,下一个位置为当前位置加上当前位置的数值,如果超过n立即停止
思路:从第一个位置开始跑,跑过的位置不需要跑第二次,最后取最大值即可
#define ll long long
const int N = 3e5 + 10 ;
int a[ N] ;
int main ( )
{
int t;
cin >> t;
while ( t-- ) {
int n;
cin >> n;
for ( int i = 1 ; i <= n; i++ ) {
cin >> a[ i] ;
}
ll ans = 0 ;
map< int , ll> res;
for ( int i = 1 ; i <= n; i++ ) {
int p = i;
ll sum = 0 ;
while ( p<= n) {
if ( res[ p] ) break ;
sum + = a[ p] ;
res[ p] = sum;
p = p+ a[ p] ;
}
ans = max ( ans, sum) ;
}
cout << ans << endl;
}
return 0 ;
}
题意:给定n个数,Alice和Bob轮流取数,Alice先手,Alice选偶数得分,Bob选奇数得分,问最后谁得分高
思路:将奇数和偶数分开从小到大排序,从大到小开始取,如果当前我要选的数大于等于对方的数,我就选我当前能得分的,否则就选择对手能得分的数,最后比较双方得分即可
#define ll long long
const int N = 200010 ;
ll a[ N] ;
int main ( )
{
int t;
cin >> t;
while ( t-- ) {
int n;
cin >> n;
vector< ll> odd, even;
ll sum1 = 0 ;
ll sum2 = 0 ;
for ( int i = 1 ; i <= n; i++ ) {
cin >> a[ i] ;
if ( a[ i] % 2 == 0 ) {
sum1 + = a[ i] ;
even. push_back ( a[ i] ) ;
} else {
sum2 + = a[ i] ;
odd. push_back ( a[ i] ) ;
}
}
ll s1 = 0 ;
ll s2 = 0 ;
sort ( odd. begin ( ) , odd. end ( ) ) ;
sort ( even. begin ( ) , even. end ( ) ) ;
int p1 = ( int ) even. size ( ) - 1 ;
int p2 = ( int ) odd. size ( ) - 1 ;
int f = 1 ;
while ( p1>= 0 || p2>= 0 ) {
if ( f== 1 ) {
if ( p1< 0 ) {
p2-- ;
} else {
if ( p2< 0 || even[ p1] >= odd[ p2] ) {
s1 + = even[ p1] ;
p1-- ;
} else {
p2-- ;
}
}
} else {
if ( p2< 0 ) {
p1-- ;
} else {
if ( p1< 0 || odd[ p2] >= even[ p1] ) {
s2 + = odd[ p2] ;
p2-- ;
} else {
p1-- ;
}
}
}
f = - f;
}
if ( s1== s2) {
cout << "Tie" << endl;
} else if ( s1> s2) {
cout << "Alice" << endl;
} else {
cout << "Bob" << endl;
}
}
return 0 ;
}
题意:给定n组h,w,问每组是否存在一个除自己以外满足(hj<hi&&wj<wi)||(hj<wi&&hi<wj)的元组,不存在输出-1
思路:按照h从小到大排序,然后按照这个顺序从1开始到i的w的最小值存在minn数组里,第一种情况,遍历h找到小于hi的h下标j,对应得minn.wj小于wi即满足,第二种情况,遍历w找到小于wi得h得下标j,对应得minn.wj小于hi即满足
const int N = 2e5 + 10 ;
int h[ N] , w[ N] ;
int res[ N] ;
struct cc
{
int da, p;
} minn[ N] ;
struct node
{
int h, w, p;
} s[ N] ;
bool cmp1 ( node a, node b)
{
if ( a. h== b. h) {
return a. w < b. w;
}
return a. h < b. h;
}
int main ( )
{
int t;
cin >> t;
while ( t-- ) {
int n;
cin >> n;
for ( int i = 1 ; i <= n; i++ ) {
cin >> h[ i] >> w[ i] ;
s[ i] . h = h[ i] ;
s[ i] . w = w[ i] ;
s[ i] . p = i;
}
map< int , int > ans;
sort ( s+ 1 , s+ 1 + n, cmp1) ;
minn[ 1 ] . da = s[ 1 ] . w;
minn[ 1 ] . p = s[ 1 ] . p;
res[ 1 ] = s[ 1 ] . h;
for ( int i = 2 ; i <= n; i++ ) {
if ( s[ i] . w< minn[ i- 1 ] . da) {
minn[ i] . da = s[ i] . w;
minn[ i] . p = s[ i] . p;
} else {
minn[ i] . da = minn[ i- 1 ] . da;
minn[ i] . p = minn[ i- 1 ] . p;
}
res[ i] = s[ i] . h;
}
for ( int i = 2 ; i <= n; i++ ) {
int p = lower_bound ( res+ 1 , res+ n+ 1 , s[ i] . h) - res- 1 ;
if ( p== 0 ) continue ;
if ( minn[ p] . da< s[ i] . w) {
ans[ s[ i] . p] = minn[ p] . p;
}
}
for ( int i = 1 ; i <= n; i++ ) {
int p = lower_bound ( res+ 1 , res+ n+ 1 , s[ i] . w) - res- 1 ;
if ( p== 0 ) continue ;
if ( minn[ p] . da< s[ i] . h) {
ans[ s[ i] . p] = minn[ p] . p;
}
}
for ( int i = 1 ; i <= n; i++ ) {
if ( i!= 1 ) cout << " " ;
if ( ans[ i] == 0 ) {
cout << - 1 ;
continue ;
}
cout << ans[ i] ;
}
cout << endl;
}
return 0 ;
}