CH Round#58 OrzCC杯NOIP模拟赛day2-颜色问题

来源:互联网 发布:java 文件夹监听 编辑:程序博客网 时间:2024/05/16 10:54

【背景及描述】
       XX 城堡有 n 个房间,每个房间都被装饰成一种颜色,记第 i 个房间的颜色为 Ci,外面的人无
法进入这个城堡,但是可以通过里面的仆人了解到这些房间的颜色。这些仆人正好有 n 个,他们要
打扫这些房间。他们有奇怪的规则:第一天第 i 个仆人打扫第 i 个房间,第二天第 i 个仆人打扫第
i+1 个房间(若 i=n,则他打扫第 1 个房间),第三天第 i 个仆人打扫第 i+2 个房间(若 i=n-1,
他打扫第 1 个房间;若 i=n,他打扫第 2 个房间),以此递推循环下去。每个仆人都有自己最喜欢
的颜色,当他打扫一个房间后,他会告诉你这个房间颜色是不是 c(c 为这个仆人最喜欢的颜色)。
某人对这个城堡很有兴趣,你想知道他在第几天才能完全了解到所有房间的颜色。
【输入格式】
       输入有 3 行,第一行有一个正整数 n。第二行有 n 个整数,表示每个房间的颜色。第三行有 n
个整数,表示每个仆人最喜欢的颜色。
【输出格式】
       输出只有一个正整数,如题所述;如果答案为无穷大,请输出-1。

 

 

第一眼看到这题的时候就想到noip的那道篝火晚会。。有一点相似吧。。所以我们的任务就是找出每一个房间最早被知道颜色的时间,这里说一下我的想法吧。。

无解的情况很好判断,用一个标记数组,如果仆人中有c颜色就将c的标记打上,再扫描房间,如果有某个房间的颜色没有标记,那么就无解。。

接下来我们以颜色为第一关键字,位置为第二关键字对房间和仆人排序,因为无解的情况已排除,所以每一个房间都对应着至少一个同颜色的人。。排序之后每个颜色对应的都是一个连续的区间,我们记录下每个颜色在排序后的仆人数组中的左右下标,然后再扫描房间数组,对于每一个房间都扫描他的颜色对应的区间,更新答案即可。。不过这样虽然可以AC,时间复杂度没有保证,可以轻松构造数据卡掉。。所以还是看标解的好。。

代码:

<pre name="code" class="cpp">#include#include#include#includeusing 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.cint 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)
0 0
原创粉丝点击