【背景及描述】
法进入这个城堡,但是可以通过里面的仆人了解到这些房间的颜色。这些仆人正好有 n 个,他们要
打扫这些房间。他们有奇怪的规则:第一天第 i 个仆人打扫第 i 个房间,第二天第 i 个仆人打扫第
i+1 个房间(若 i=n,则他打扫第 1 个房间),第三天第 i 个仆人打扫第 i+2 个房间(若 i=n-1,
他打扫第 1 个房间;若 i=n,他打扫第 2 个房间),以此递推循环下去。每个仆人都有自己最喜欢
的颜色,当他打扫一个房间后,他会告诉你这个房间颜色是不是 c(c 为这个仆人最喜欢的颜色)。
某人对这个城堡很有兴趣,你想知道他在第几天才能完全了解到所有房间的颜色。
【输入格式】
个整数,表示每个仆人最喜欢的颜色。
【输出格式】
第一眼看到这题的时候就想到noip的那道篝火晚会。。有一点相似吧。。所以我们的任务就是找出每一个房间最早被知道颜色的时间,这里说一下我的想法吧。。
无解的情况很好判断,用一个标记数组,如果仆人中有c颜色就将c的标记打上,再扫描房间,如果有某个房间的颜色没有标记,那么就无解。。
接下来我们以颜色为第一关键字,位置为第二关键字对房间和仆人排序,因为无解的情况已排除,所以每一个房间都对应着至少一个同颜色的人。。排序之后每个颜色对应的都是一个连续的区间,我们记录下每个颜色在排序后的仆人数组中的左右下标,然后再扫描房间数组,对于每一个房间都扫描他的颜色对应的区间,更新答案即可。。不过这样虽然可以AC,时间复杂度没有保证,可以轻松构造数据卡掉。。所以还是看标解的好。。
代码:
<pre name="code" class="cpp">#include
#include
#include
#include
using namespace std;
const int maxn=100005;
struct col{
int c,w;
};
col a[maxn],room[maxn];
int i,n,h,t,ans,h1,c[1000005],del[maxn];
bool cmp(col a,col b){return a.c
int main()
{
scanf("%d",&n);
memset(c,0,sizeof(c));
for (i=1;i<=n;i++)
scanf("%d",&room[i].c);
for (i=1;i<=n;i++)
{
scanf("%d",&a[i].c);
c[a[i].c]++;
a[i].w=i;
room[i].w=i;
}
for (i=1;i<=n;i++)
if (!c[room[i].c])
{
printf("-1\n");
return0;
}
sort(room+1,room+n+1,cmp);
sort(a+1,a+n+1,cmp);
memset(del,30,sizeof(del));
h=1;
for (i=1;i<=n;i++)
{
while (room[i].c!=a[h].c)h++;
h1=h;
while (room[i].c==a[h].c)
{
t=room[i].w-a[h].w;
if (t<0)t+=n;
del[i]=min(del[i],t);
h++;
}
h=h1;
}
ans=0;
for (i=1;i<=n;i++)
ans=max(ans,del[i]);
printf("%d\n",ans+1);
}
- (2014-10-23 10:22:06)
- (2014-10-14 18:23:34)
- (2014-08-21 19:07:13)
- (2014-08-16 14:59:50)