CodeForces 534D-B - Handshakes-模拟水题

题意:有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;
	
}



你可能感兴趣的:(CodeForces 534D-B - Handshakes-模拟水题)