样例1:
输入:
8
4
1 2 5 2
BRBR
2
1 1
BB
5
3 1 4 2 5
RBRRB
5
3 1 3 1 3
RBRRB
5
5 1 5 1 5
RBRRB
4
2 2 2 2
BRBR
2
1 -2
BR
4
-2 -1 4 0
RRRR
输出:
YES
NO
YES
YES
NO
YES
YES
YES
思路:贪心。
贪心策略:设B有x个,则R有n-x个。让B和R的优势都发挥出来,即让B尽可能变小,变成1~x的数;让R尽可能变大,变成值的范围为x+1~n的数。B往后排,R往前排。
先排B再排R,即先按BBBRRR排列,再按1234排列。
正确代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int t, n;
struct aa
{
int v; // 值
char color; // 颜色 r变大,b变小
} a[N];
bool cmp(aa a, aa b)
{
if (a.color == b.color)
return a.v < b.v;
else
return a.color < b.color;
}
int main()
{
cin >> t;
while (t--)
{
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i].v;
for (int i = 0; i < n; i++)
cin >> a[i].color;
sort(a, a + n, cmp);
int flag = 1; // 默认yes
for (int i = 0; i < n; i++)
{
if (a[i].color == 'B' && a[i].v < i + 1)
{
flag = false;
break;
}
if (a[i].color == 'R' && a[i].v > i + 1)
{
flag = false;
break;
}
}
if (flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}
ps:下面是一个错误代码,样例都过不去,结果居然AC了。。
(下面代码的贪心策略错了,cmp中不应该先判断值再判断颜色,应该反过来)
(如果输入为1,-2,则排序后先对-2分析,color为R可以增大为1;再对1分析,color为B,只能减小不能增大为2,所以输出了NO,但应该输出YES)
#include <bits/stdc++.h>
using namespace std;
const int N = 10;
int t, n;
struct aa
{
int v; // 值
char color; // 颜色 r变大,b变小
bool st = false; // 是否被选中
};
bool cmp(aa a, aa b)
{
if (a.v < b.v)
return true;
else if (a.v == b.v && a.color == 'B' && b.color == 'R')
return true;
return false;
}
vector<aa> a;
int main()
{
cin >> t;
while (t--)
{
a.clear();
cin >> n;
int x[N];
char y[N];
for (int i = 0; i < n; i++)
cin >> x[i];
for (int i = 0; i < n; i++)
cin >> y[i];
for (int i = 0; i < n; i++)
a.push_back({x[i], y[i]});
//>n要减小 <1要增大
sort(a.begin(), a.end(), cmp); // r变大,b变小
int flag = 1; // 默认yes
for (auto i : a)
{
if (i.v < 1)
{
if (i.color == 'B')
{
cout << "NO" << endl;
flag = 0;
break;
}
}
else if (i.v > n)
{
if (i.color == 'R')
{
cout << "NO" << endl;
flag = 0;
break;
}
}
}
if (flag == 0)
{
continue;
}
int j = 1; // 1~n
for (vector<aa>::iterator i = a.begin(); i != a.end(); i++)
{
if ((*i).v == j && (*i).st == false)
{
(*i).st = true;
j++;
}
else if ((*i).v != j && (*i).st == false)
{
if ((*i).v > j && (*i).color == 'B')
{
(*i).v = j;
(*i).st = true;
j++;
}
else if ((*i).v < j && (*i).color == 'R')
{
(*i).v = j;
(*i).st = true;
j++;
}
else if ((*i).v > j && (*i).color != 'R') // 找r
{
for (auto k = i; k < a.end(); k++)
{
if ((*k).v > j && (*k).color == 'R' && (*k).st == false)
{
(*k).v = j;
(*k).st = true;
j++;
swap((*i), (*k));
break;
}
}
}
else if ((*i).v < j && (*i).color != 'B') // 找b
{
for (auto k = i; k < a.end(); k++)
{
if ((*k).v < j && (*k).color == 'B' && (*k).st == false)
{
(*k).v = j;
(*k).st = true;
j++;
swap((*i), (*k));
break;
}
}
}
}
}
int t = 1;
int f = 1; // 默认yes
for (auto i : a)
{
if (i.v != t)
{
f = 0;
cout << "NO" << endl;
break;
}
else
{
t++;
}
}
if (f == 1)
{
cout << "YES" << endl;
}
}
}
(样例倒数第二个输出不对,但也AC了。。)