题目:
http://codeforces.com/contest/1081/problem/B
官方题解:
我的代码:
//2
#include<stdio.h>
#include<string.h>
#include<set>
using namespace std;
#define MAXN 100010
int a[MAXN],b[MAXN];
int used[MAXN],used_v[MAXN];
int Set[MAXN];
//multiset<int>B;
int main()
{
int i,j;
int n;
int num,cnt;
bool flag=false;
int ans;
scanf("%d",&n);
//B.clear();
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
//B.insert((n-a[i]));
Set[n-a[i]]++;
b[i]=n-a[i];
}
for(i=1;i<=n;i++)
{
//if(B.count(b[i])%b[i]!=0)
if(Set[b[i]]%b[i]!=0)
{
printf("%s\n","Impossible");
return 0;
}
}
printf("%s\n","Possible");
cnt=0;
used_v[b[1]]=1;
for(i=1;i<=n;i++)
{
if(used[b[i]]%b[i]!=0)
ans=used_v[b[i]];
else
{
++cnt;
used_v[b[i]]=cnt;
ans=cnt;
}
if(!flag)
{
flag=true;
printf("%d",ans);
}
else
printf(" %d",ans);
used[b[i]]++;
}
printf("\n");
return 0;
}
其实关键是:
这样的输出方式有一个很好的测试样例:
10
7 7 7 7 7 9 8 8 7 9
因为有一个3和前面断开,但是与第4和第5个3共享一套服装序号,所以要用数组存起来上一次3是用了多少序号。
同时:
这是为了应对连续5个3的时候,第4和第5个三应该和1 2 3号的服装序号不同。
还有,一开始用了multiset,虽然整体代码是O(n)的,而且每次multiset操作都是O(logn),但是集合中的元素会自动进行排序,所以stl容易超时,n=100000的时候必定超时,所以改用数组代替其功能。