https://cn.vjudge.net/contest/291737#problem/G
分糖果
万圣节到了,杰哥准备给班级里的同学发糖吃,男生女生各一堆。于是他去腐败街的xx小卖部买糖,他认为糖只要是独一无二的那他就是好糖,他跟老板说他想要买n个不一样的糖,但是老板是个黑心商贩,当杰哥把糖带回去的时候才发现有挺多相同的糖,而杰哥是一个公平正直的人,他希望男生女生两堆糖中好糖的数量相同,于是他想找你帮忙来解决他的烦恼。
为了简化问题我们将不同的糖用不用的数字表示。
Input
第一行输入一个整数 n(2<=n<=100)
第二行输入n个整数 s1,s2,...sn(1<=si<=100)表示第i个糖是哪种糖
Output
如果杰哥无法将这些糖合理的分成2份则输出一行"NO"
如果可以 则输出一行"YES"下一行输出n个字符,第i个字符表示第i个糖属于男生还是女生(女生输出A,男生输出B)
情况有多种,任选一种情况输出即可。
Examples
Input
4 3 5 7 1
Output
YES BABA
Input
3 3 5 1
Output
NO
题目描述的是要求男女能分到相同数目的独一无二的糖,如果不能就输出NO. 我本来以为的是一个种类的糖只出现一次,才能被称为独一无二的糖,比赛过后听别人说,才知道原来只要男生或者女生手里这种糖的数目只有一个就能被称为是独一无二的糖。因此需要对出现3次或者出现1次的糖进行讨论与判定(因为一个糖如果出现了两次,男女各一个,对独一无二的糖的总数目的奇偶性不产生影响,所以不过多的进行讨论)。对于该题我使用了多次标记的方法,初始flag的值为0,并定义了一个mark数组,一个dis数组进行标记。
emmmm。
还是直接上代码吧
#include <iostream>
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int n,pre[102];
int dis[102];
int mark[102];
int main()
{
cin>>n;
int sum=0;
int flag=0;
for(int i=1; i<=n; i++)
{
cin>>pre[i];
dis[pre[i]]++;//如果一个出现了一次就让他的dis加一
}
memset(mark,0,sizeof(mark));
for(int i=1; i<=n; i++)
{
if(dis[pre[i]]==1)
sum++;
else if(dis[pre[i]]==2)
{
sum+=2;
mark[pre[i]]=1; }
else
{
if(flag==0)//若一种糖的数目大于2,且第一次出现,就把flag值改为1,mark改为2
{
flag=1;
mark[pre[i]]=2;
}
}
}
if(sum%2==1&&flag)//如果只出现一次的糖的种类为奇数就对flag值进行判定
{
sum+=1;
flag=2;
}
if(sum%2==1)//为奇数输出NO
printf("NO\n");
else
{
printf("YES\n");
int l1=1,l2=1;//对所出现的糖进行处理,以输出不同的字母
for(int i=1;i<=n;i++)
{
if(dis[pre[i]]==1)
{
if(l1%2==1)
printf("A");
else
printf("B");
l1++;
}
else if(mark[pre[i]]==2&&flag==2)//保证该种糖不会再一次出现在男生或女生中
{
if(l1%2==1)
{
printf("A");
mark[pre[i]]=3;
}
else
{
printf("B");
mark[pre[i]]=4;
}
l1++;
}
else if(mark[pre[i]]==1)
{
if(l2==1)
printf("A");
else
printf("B");
l2=(l2+1)%2;
}
else if(mark[pre[i]]==3)
printf("B");
else if(mark[pre[i]]==4)
printf("A");
else
printf("B");
}
printf("\n");
}
return 0;
}