座位争执--Vijos P1245 (校内Vijos P1361)

 

描述

还记得Matrix67的“非常男女”计划吗?由Matrix67策划的学校大型男女配对活动将在大礼堂隆重举行,学校里许多人即将前来捧场。大礼堂一共有n个座位,为了方便管理,Matrix67对它们从1到n顺序编号。售票工作已经完成,经统计,共有k个人拿到了入场券。由于k<n,因此大礼堂的座位完全足够。每张入场券上都印有座位号,入场者凭入场券对号入座。在这k个人即将陆续入场时,Matrix67发现了一个严重的错误:由于在入场券的销售过程中搞错了大礼堂总的座位数,入场券上印的座位号只有1到t。虽然这t个座位号中的每一个都在入场券中至少出现了一次,但有一个事实不能改变:t<k。也就是说,这k个人中有一些人的入场券上印有相同的座位号。这样,入场时必将发生很多次座位的争执。我们假定,当一个人入场后发现了他该坐的位置上已经有了人,此时这两个人将发生一次争执,争执的结果总是这个人不能夺回座位;此时该人继续寻找下一个座位号并可能再次发生争执,直到找到一个空位置为止。Matrix67必须调整这k个人的入场顺序,使得总的座位争执发生的次数最少。

格式

输入格式

第一行有三个用空格隔开的正整数n、k、t,它们分别表示总的座位数、实际到场人数和入场券上的最大座位号,它们满足关系n>k>t。

第二行有k个用空格隔开的正整数。这些正整数保证不超过t,且所有不超过t的正整数总会在这些数中出现至少一次。它们表示这k个人的入场券上印的座位号。

对于30%的数据,n<=10;
对于50%的数据,n<=1000;
对于100%的数据,n<=100 000。

输出格式

输出发生争执的最少次数。

题目缩写:

大礼堂一共有n个座位,Matrix67对它们从1n顺序编号。

共有k个人拿到了入场券。由于k<n,因此大礼堂的座位完全足够。每张入场券上都印有座位号,入场者凭入场券对号入座。

入场券上印的座位号只有1t

t个座位号中的每一个都在入场券中至少出现了一次,t<k

k个人中有一些人的入场券上印有相同的座位号。

入场时必将发生很多次座位的争执。

当一个人入场后发现了他该坐的位置上已经有了人,此时这两个人将发生一次争执,争执的结果总是这个人不能夺回座位;此时该人继续寻找下一个座位号并可能再次发生争执,直到找到一个空位置为止。调整这k个人的入场顺序,使得总的座位争执发生的次数最少。

说实话,一开始我想到了《Beauty of Programing》 4.1 金刚坐飞机、

好吧,没什么大关系、

容易证明,所有排列的效果相同,所以先有了这个枚举版:

 1 Var
 2   a:Array[0..100001] of longint;
 3   Iris,Tt:int64;
 4   j,n,k,t,i:longint;
 5 Begin
 6   Read(n,k,t);
 7   For i:=1 to k do
 8     Begin
 9       Read(Tt);
10       if a[Tt]=0 Then a[Tt]:=1
11       Else
12         Begin
13           Inc(Iris);
14           For j:=1 to k do
15             if a[Tt+j]>0 Then Inc(Iris)
16             Else
17               Begin
18                 a[Tt+j]:=1;
19                 Break;
20               End;
21         End;
22     End;
23   Writeln(Iris);
24 End.

实践证明,在我们学校服务器,你会得到如下结果

     
 
编译通过...
测试数据1:答案正确... 0ms
测试数据2:答案正确... 0ms
测试数据3:答案正确... 0ms
测试数据4:答案正确... 0ms
测试数据5:答案正确... 72ms
测试数据6:运行超时...
测试数据7:答案正确... 0ms
测试数据8:运行超时...
测试数据9:运行超时...
测试数据10:答案正确... 0ms
-------------------------
Unaccepted 有效得分:70 有效耗时:72ms

 

P.S. 6/8/9是大数据点、

 

我们再仔细看题,发现保证每个t以内座位上都有人,所以、、、、、

只需要在每个座位上加上所有人数,然后依次使每个座位上只有一个人即可(人是一样的啊、、)

有了以下代码

 1 Var
 2   a:Array[0..100001] of longint;
 3   Iris,Tt:longint;
 4   n,k,t,i:longint;
 5 Begin
 6   Read(n,k,t);
 7   For i:=1 to k do
 8     Begin
 9       Read(Tt);
10       Inc(a[Tt]);
11     End;
12   For i:=1 to k do
13     if (a[i]=0) Or (a[i]=1) Then Continue
14     Else
15       Begin
16         Iris:=Iris+a[i]-1;
17         a[i+1]:=a[i+1]+a[i]-1;
18       End;
19   Writeln(Iris);
20 End.

但很遗憾,

   
 
编译通过...
测试数据1:答案正确... 0ms
测试数据2:答案正确... 0ms
测试数据3:答案正确... 0ms
测试数据4:答案正确... 0ms
测试数据5:答案正确... 0ms
测试数据6:答案错误...
测试数据7:答案正确... 0ms
测试数据8:答案错误...
测试数据9:答案错误...
测试数据10:答案正确... 0ms
-------------------------
Unaccepted 有效得分:70 有效耗时:0ms

 这是为什么?、、、

Vijos很坑的不会告诉你是不够大的、、(不论是老旧的Vijos(2005~2006),还是新的Vijos.org)

由题,我们可以发现,在极不利的情况下,答案是完全可以爆掉Maxlongint的!!!!

所以,改成int64

 

评测结果(来自Vijos.org)

编译成功

测试数据 #0: Accepted, time = 7 ms, mem = 1212 KiB, score = 10

测试数据 #1: Accepted, time = 0 ms, mem = 1212 KiB, score = 10

测试数据 #2: Accepted, time = 0 ms, mem = 1216 KiB, score = 10

测试数据 #3: Accepted, time = 0 ms, mem = 1216 KiB, score = 10

测试数据 #4: Accepted, time = 11 ms, mem = 1220 KiB, score = 10

测试数据 #5: Accepted, time = 15 ms, mem = 1216 KiB, score = 10

测试数据 #6: Accepted, time = 15 ms, mem = 1212 KiB, score = 10

测试数据 #7: Accepted, time = 31 ms, mem = 1212 KiB, score = 10

测试数据 #8: Accepted, time = 15 ms, mem = 1216 KiB, score = 10

测试数据 #9: Accepted, time = 31 ms, mem = 1212 KiB, score = 10

Accepted, time = 125 ms, mem = 1220 KiB, score = 100

启示:
细心,耐心、、、
细节、、
posted @ 2013-09-27 21:46  Iris.Catch-22.S、`  阅读(366)  评论(0编辑  收藏  举报