B - ZgukistringZ 给出字符串a b c,问a重组后(各字母数量不变,位置可变)最多能包含多少个不重叠的b或c的子串
枚举b出现的次数(0到最多出现的次数),然后不断求c的次数,再更新答案
const int N = 100020;
char a[N], b[N], c[N];
int n;
int z[30], x[32], y[30];
int main()
{
while( ~scanf("%s%s%s", a, b, c) ) {
memset( x, 0, sizeof( x ) );
memset( y, 0, sizeof( y ) );
memset( z, 0, sizeof( z ) );
int len1 = strlen(a), len2 = strlen(b), len3 = strlen(c);
for( int i = 0; i < len1; ++i )
x[a[i]-'a']++;
for( int i = 0; i < len2; ++i )
y[b[i]-'a']++;
for( int i = 0; i < len3; ++i )
z[c[i]-'a']++;
int bb = inf, cc = inf;
for( int i = 0; i < 26; ++i ) {
if( !y[i] )
continue;
bb = min( bb, x[i] / y[i] );
}
for( int i = 0; i < 26; ++i ) {
if( !z[i] )
continue;
cc = min( cc, x[i] / z[i] );
}
if( !bb && !cc ) {
puts(a);
continue;
}
int ans = 0, buse, cuse;
for( int i = 0; i <= bb; ++i ) {
int tmp = inf;
for( int j = 0; j < 26; ++j ) {
if( !z[j] )
continue;
tmp = min( tmp, (x[j] - i*y[j]) / z[j] );
}
if( ans < i + tmp ) {
ans = i + tmp;
buse = i, cuse = tmp;
}
}
//printf("%d %d\n", buse, cuse);
for( int i = 1; i <= buse; ++i )
printf("%s", b);
for( int i = 1; i <= cuse; ++i )
printf("%s", c);
for( int i = 0; i < 26; ++i ) {
x[i] = x[i] - buse * y[i] - cuse * z[i];
for( int j = 1; j <= x[i]; ++j )
printf("%c", i + 'a');
}
puts("");
}
return 0;
}
C - GukiZ hates Boxes n堆东西需要m个学生去搬,最开始m个学生在位置0,每移动一个位置需要一秒,每搬开一堆东西里面的一个东西也需要一秒,问最少多少秒搬开所有东西。
二分时间然后通过m个学生能否在时间内完成来判断
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <iomanip>
#include <algorithm>
using namespace std;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define ls rt << 1
#define rs rt << 1 | 1
#define pi acos(-1.0)
#define eps 1e-8
#define asd puts("sdfsdfsdfsdfsdfsdf");
typedef long long ll;
///typedef __int64 LL;
const int inf = 0x3f3f3f3f;
const int N = 100100;
int n, m;
ll a[N], tmp[N];
bool f( ll t )
{
memcpy( tmp, a, sizeof tmp );
ll x, pos = n;
for( int i = 1; i <= m; ++i ) {
while( tmp[pos] == 0 && pos > 0 )
pos--;
if( pos == 0 )
return 1;
x = t - pos;
if( x <= 0 )
return 0;
while( x >= tmp[pos] && pos > 0 ) {
x -= tmp[pos];
pos--;
}
if( pos > 0 )
tmp[pos] -= x;
}
return pos <= 0;
}
int main()
{
while( ~scanf("%d%d", &n, &m ) ) {
ll l = 0, r = 1LL * inf * n;
for( int i = 1; i <= n; ++i ) {
scanf("%lld", &a[i]);
}
ll ans;
while( l <= r ) {
int mid = ( l+r ) >> 1;
if( f( mid ) ) {
ans = mid;
r = mid-1;
}
else
l = mid+1;
}
printf("%lld\n", ans);
}
return 0;
}