题意:有n个人,依次进入一个大厅,每个人进入大厅会和里面闲着的人握手,
只要凑齐三个人,那三个人便可以一起去玩游戏,玩游戏过程中他们不会与别人握手(相当于死了....)
注意,在整个过程的任意时刻,都可以选择去玩游戏(三个人可以在任意时间组队)
给n,n个数,表示第i个人与别人握手的次数
问你给出的数组是否合法,如果合法 输出他们分别进入大厅的次序,否则输出impossible
用vector【i】把 次数为i的人都push进去
while(1)
{
如果次数为0 的人存在 且当前空闲人数为0 ,则表示0这个数是合法的,从vector取出一个序号,并从vector删除
接下来判断次数为1,次数为2
--------------------------------
然后如果到这里时,当前大厅空闲人数小于三,且所有vector的序号都用掉了,则表示合法,否则就一定是不合法的(存在不可能的握手次数)
如果人数大于三,接下来把能进来的人依次让他们进来,
接下来,开始考要让三个人组队去玩游戏,由于 (三个人可以在任意时间组队)
所以不能一次性把人数模3,而是每次减掉三个人,看能否继续进,直到小于三。。。。【就是这里wa了2次】
}
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
vector<int> ans[200005];
vector<int> ::iterator it;
int tm[200005];
vector<int> sb;
int main()
{
int n;
int i;
scanf("%d",&n);
int tmp;
for (i=1;i<=n;i++)
{
scanf("%d",&tmp);
tm[tmp]++;
ans[tmp].push_back(i);
}
int cun=0;
while(1)
{
if(tm[0]&&cun==0)
{
tm[0]--;
cun++;
it=ans[0].end();
it--;
sb.push_back(*it);
ans[0].erase(it);
}
if(tm[1]&&cun==1)
{
tm[1]--;
cun++;
it=ans[1].end();
it--;
sb.push_back(*it);
ans[1].erase(it);
}
if(tm[2]&&cun==2)
{
tm[2]--;
cun++;
it=ans[2].end();
it--;
sb.push_back(*it);
ans[2].erase(it);
}
if (cun<3)
{
int flag=0;
for (i=0;i<n;i++)
{
if (tm[i])
{
flag=1;
break;
}
}
if (flag)
{
printf("Impossible\n");
return 0;
}
else
{
break;
}
}
for (i=cun;i<n;i++)
{
if (tm[i])
{
tm[i]--;
cun++;
it=ans[i].end();
it--;
sb.push_back(*it);
ans[i].erase(it);
}
else
break;
}
if (cun>=3)
cun=cun-3;
}
printf("Possible\n");
for (i=0;i<sb.size();i++)
{
if (i!=0) printf(" ");
printf("%d",sb[i]);
}
printf("\n");
return 0;
}