标签:
D:
题目大意:两个人进行比赛,我们只知道进行了N局比赛的结果,N局之后有一个人赢得了最终的比赛。1代表第一个人赢,2代表第二个人赢。给你他们的输赢情况,让你求出来怎么安排比赛才能得到这种情况,输出时,先按S排序,如果S相同按照T排序。按顺序输出所有的S,T。
思路:我们可以预处理出来在第几的位置某个人赢了x场。
比如:
8
2 1 2 1 1 1 1 1
我们需要枚举赢k场比赛算赢了一小场,注意最后赢的人一定必须是这一局的胜利者。
枚举k之后我们从0开始向后找比如k = 2, xpos代表1赢k场的位置,ypos代表2赢k场的位置。我们找到xpos = 4,ypos = 3,所以如果赢两次算赢一小局的话,2赢下了第一小局。之后2要找赢的两场之后的位置就是sum2=y+k的位置,此时没有,1要找1+k的位置(因为在2赢下一小局的时候1的有一小节是不再被带到下一小局的,所以他如果赢的下一小局的话,就要找到x(到胜负确定的位置时,已经有几小节1结束了)+k(下一次要赢的次数)的位置)。此时xpos
= 5,依此类推下去。。。但是需要注意的是在最后一次的比赛的时候1要解决这一小局的比赛,但是k=2时,显然1结局不了最后一局,所以k = 2,不满足条件。
这里找到下一次x+k或者y+k的位置是可以用二分枚举前缀和,也可以hash处理出来所有的和,O(1)的寻找。
<span style="font-size:18px;">#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <time.h>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
#define LL long long
//#define LL long long
#define INF 0x3f3f3f
#define PI 3.1415926535898
#define read() freopen("data1.in", "r", stdin)
#define write() freopen("data1.out", "w", stdout);
const int maxn = 200010;
using namespace std;
int sum1[maxn];
int sum2[maxn];
struct node
{
int sum, pos;
int flag;
};
node f[maxn], p[maxn];
struct N
{
int x, y;
} fx[maxn];
bool cmp(N a, N b)
{
if(a.x == b.x) return a.y < b.y;
return a.x < b.x;
}
int num[maxn];
int main()
{
int n;
while(cin >>n)
{
for(int i = 1; i <= n; i++) scanf("%d",&num[i]);
int cnt = 0;
sum1[0] = 0;
sum2[0] = 0;
for(int i = 1; i <= n; i++)
{
f[i].flag = p[i].flag = 0;
f[i].pos = p[i].pos = 0;
if(num[i] == 1)
{
sum1[i] = sum1[i-1]+1;
sum2[i] = sum2[i-1];
continue;
}
sum1[i] = sum1[i-1];
sum2[i] = sum2[i-1]+1;
}
for(int i = n; i >= 1; i--)
{
f[sum1[i]].pos = i;
f[sum1[i]].sum = sum1[i];
f[sum1[i]].flag = 1;
p[sum2[i]].pos = i;
p[sum2[i]].sum = sum2[i];
p[sum2[i]].flag = 1;
}
///for(int i = 1; i <= n; i++) cout<<num[n]<<endl;
for(int i = 1; i <= n; i++)
{
int x = 0;
int y = 0;
int xsum1 = 0;
int xsum2 = 0;
int xx = 0, yy = 0;
int xflag = 0;
while(x < n && y < n)
{
///cout<<x<<" "<<y<<endl;
int xpos = 0;
int ypos = 0;
if(f[x+i].flag) xpos = f[x+i].pos;
if(p[y+i].flag) ypos = p[y+i].pos;
if(!xpos && !ypos) break;
if(xpos && ypos)
{
if(xpos < ypos)
{
xsum1++;
x = sum1[xpos];
y = sum2[xpos];
xx = xpos;
}
else
{
xsum2++;
x = sum1[ypos];
y = sum2[ypos];
xx = ypos;
}
}
else if(xpos)
{
xsum1++;
x = sum1[xpos];
y = sum2[xpos];
xx = xpos;
}
else if(ypos)
{
xsum2++;
x = sum1[ypos];
y = sum2[ypos];
xx = ypos;
}
}
if(xflag) continue;
if(xx != n ) continue;
if(xsum1 > xsum2 && (num[n] == 1))
{
fx[cnt].x = xsum1;
fx[cnt++].y = i;
}
else if(xsum2 > xsum1 && (num[n] == 2))
{
fx[cnt].x = xsum2;
fx[cnt++].y = i;
}
}
sort(fx, fx+cnt, cmp);
cout<<cnt<<endl;
for(int i = 0; i < cnt; i++) cout<<fx[i].x<<" "<<fx[i].y<<endl;
}
return 0;
}
</span>
E:和上海区域赛的题目好像,当时慢慢的都是泪啊,sad。。。
整体来说就是一个按照边界排序后的贪心,需要用到STL。
题目大意:每个人都有一个音域,而每个乐队对音域的要求不一样,每个乐队还有一个人数限制,让你把所有的人都安排到乐队当中求,如果安排不下输出“NO”否则输出“YES”,并且输出每个人属于哪个乐队。
思路:人的声音音域,和乐队的要求按照右边r排序,然后枚举每个乐队,把符合的人都送进set里面去,然后找k次,二分set里面的左边l,如果满足l1 >= l2的话说明包含在里面就记录一下然后从set里面丢出来。
You are an assistant director in a new musical play. The play consists of n musical parts, each part must be performed by exactly one actor.
After the casting the director chose m actors who can take part in the play. Your task is to assign the parts to actors. However, there are several limitations.
First, each actor has a certain voice range and there are some parts that he cannot sing. Formally, there are two integers for each actor, ciand di (ci?≤?di) —
the pitch of the lowest and the highest note that the actor can sing. There also are two integers for each part — aj and bj(aj?≤?bj) —
the pitch of the lowest and the highest notes that are present in the part. The i-th actor can perform the j-th
part if and only if ci?≤?aj?≤?bj?≤?di,
i.e. each note of the part is in the actor‘s voice range.
According to the contract, the i-th actor can perform at most ki parts.
Besides, you are allowed not to give any part to some actors (then they take part in crowd scenes).
The rehearsal starts in two hours and you need to do the assignment quickly!
Output
If there is an assignment that meets all the criteria aboce, print a single word "YES" (without the quotes) in the first line.
In the next line print n space-separated integers. The i-th
integer should be the number of the actor who should perform the i-th part. If there are multiple correct assignments, print any of them.
If there is no correct assignment, print a single word "NO" (without the quotes).
<span style="font-size:18px;">#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <time.h>
#include <map>
#include <set>
#define eps 1e-8
#define M 1000100
#define LL long long
//#define LL long long
#define INF 0x3f3f3f
#define PI 3.1415926535898
#define read() freopen("data1.in", "r", stdin)
#define write() freopen("data1.out", "w", stdout);
const int maxn = 200010;
using namespace std;
struct node
{
LL l, r, k;
LL pos, ans;
bool operator < (const node & b) const
{
if(r == b.r) return l < b.l;
return r < b.r;
}
};
node f[maxn], p[maxn];
bool cmp(node a, node b)
{
return a.pos < b.pos;
}
struct Point
{
LL l, r, pos;
bool operator < (const Point& b) const
{
if(l == b.l)
{
if(r == b.r) return pos < b.pos;
return r < b.r;
}
return l < b.l;
}
};
int n, m;
int main()
{
ios::sync_with_stdio(false);
while(cin >>n)
{
for(int i = 0; i < n; i++)
{
cin >>f[i].l>>f[i].r;
f[i].pos = i;
}
cin >>m;
for(int i = 0; i < m; i++)
{
cin >>p[i].l>>p[i].r>>p[i].k;
p[i].pos = i;
}
sort(f, f+n);
sort(p, p+m);
///for(int i = 0; i < m; i++) cout<<p[i].l<<" "<<p[i].r<<endl;
set<Point> s;
int cnt = n;
for(int i = 0, j = 0; i < m; i++)
{
while(j < n && f[j].r <= p[i].r)
{
s.insert((Point){f[j].l, f[j].r, j});
j++;
}
for(int sj = 0; sj < p[i].k; sj++)
{
set< Point >::iterator it;
it = s.lower_bound((Point){p[i].l, 0, 0});
if(it == s.end()) break;
f[it->pos].ans = p[i].pos+1;
s.erase(it);
cnt--;
}
}
if(s.size()!=0 || cnt)
{
cout<<"NO"<<endl;
continue;
}
sort(f, f+n, cmp);
cout<<"YES"<<endl;
for(int i = 0; i < n-1; i++) cout<<f[i].ans<<" ";
cout<<f[n-1].ans<<endl;
}
return 0;
}
</span>
Codeforces Round #283 (Div. 2) D,E
标签:
原文地址:http://blog.csdn.net/xu12110501127/article/details/42319127