A - Case of Matryoshkas 题意:两种操作,1:把单独的一个大娃娃套在一串或者一个娃娃外面。2:把单独的一个娃娃在一串娃娃的最外层取下来。每次操作1s,问最短时间内组出一个1~n的套娃(每个sz的套娃都只有1个)
hash下地址然后从1~n扫一遍即可
const int N = 100010;
int pos[N], sz[N];
int n, k;
int main()
{
while( ~scanf("%d%d", &n, &k) ) {
int ans = 0, x, m, cur;
for( int i = 1; i <= k; ++i ) {
scanf("%d", &sz[i]);
for( int j = 1; j <= sz[i]; ++j ) {
scanf("%d", &x);
if( x == 1 )
cur = i;
pos[x] = i;
}
}
for( int i = 2; i <= n; ++i ) {
if( pos[i] == cur )
continue;
else {
cur = -1;
if( sz[pos[i]] > 1 )
ans += 2;
else
ans++;
sz[pos[i]]--;
}
}
printf("%d\n", ans);
}
return 0;
}
B - Case of Fugitive 给出一维坐标上n个区间m条线段,问能否通过m条线段中n-1条线段连接n个区间,一条线段能连接两个区间的,当且只当这条线段比两个区间的最短距离大,且不超过这两个区间的两端。
易得满足两个区间能相连的范围是【li+1-ri, ri+1-li]】。把每条长度看成一条点,题目就转换为m个点要落在以前面的范围为区间上面,保证每个区间上都有一个点且每个点不重用就行了。然后就点和范围区间排序,按照满足当前点的区间的最右端最左的贪心策略就行了。
const int N = 200010;
int n, m;
struct node{
ll l, r;
int id;
bool operator < ( const node &rhs ) const {
if( r > rhs.r )
return 1;
else if( r == rhs.r )
if( l > rhs.l )
return 1;
return 0;
}
}a[N];
struct pp{
ll x;
int pos;
}p[N];
int ans[N];
priority_queue <node> q;
bool cmp( const pp &e, const pp &r )
{
return e.x < r.x;
}
bool cmp1( const node &z, const node &x )
{
return z.l < x.l;
}
int main()
{
while( ~scanf("%d%d", &n, &m) ) {
while( !q.empty() ) q.pop();
ll l, r, lll, rrr;
for( int i = 1; i <= n; ++i ) {
ans[i] = -1;
scanf("%lld%lld", &l, &r);
if( i >= 2 ) {
a[i].l = l - rrr;
a[i].r = r - lll;
a[i].id = i;
}
lll = l;
rrr = r;
///q.push(a[i]);
}
for( int i = 1; i <= m; ++i ) {
scanf("%lld", &p[i].x);
p[i].pos = i;
}
if( m < n-1 ) {
puts("No");
continue;
}
sort( p+1, p+m+1, cmp );
sort( a+1, a+1+n, cmp1 );
/*
while( !q.empty() ) {
node c = q.top();
q.pop();
printf("id: %d l: %lld r: %lld\n", c.id, c.l, c.r);
}
for( int i = 1; i <= m; ++i ) {
printf("posi: %d x: %lld\n", p[i].pos, p[i].x);
}
for( int i = 1; i <= n; ++i ) {
printf("id: %d l: %lld r: %lld\n", a[i].id, a[i].l, a[i].r);
}
*/
int cur = 2;
for( int i = 1; i <= m; ++i ) {
while( cur <= n && a[cur].l <= p[i].x ) {
q.push( a[cur] );
cur++;
}
while( !q.empty() ) {
node c = q.top();
q.pop();
if( p[i].x <= c.r ) {
ans[c.id] = p[i].pos;
break;
}
}
}
bool OK = 1;
for( int i = 2; i <= n; ++i ){
///printf("i: %d ansi: %d\n", i, ans[i]);
if( ans[i] == -1 ) {
OK = 0;
break;
}
}
if( !OK )
puts("No");
else {
puts("Yes");
for( int i = 2; i <= n; ++i )
printf("%d ", ans[i]);
puts("");
}
}
return 0;
}