1. 程式人生 > >HDU 1050(搬椅子 數學)

HDU 1050(搬椅子 數學)

struct 結果 .... aps 排列 namespace 超時 標記 view

題意是在一個有 400 個房間的走廊中搬動房間裏的椅子,如果兩次的路線重疊,就要分兩次搬動,如果不重疊,就可以一次搬動。

開始的時候直接當成求線段重疊條數的題,發現這種思路完全是錯的,比如 1 - 3,2 - 4,3 - 5 這一組,只需搬動兩次即可,但找重疊線段的話就會找到 3 條重疊線段。

然後打算直接模擬做,加入一點貪心的思路,用結構體數組存搬動要求,按椅子搬動的距離從小到大排序,掃描一邊整個結構體數組,將搬動的路徑標記,

若已經標記過,則 ++ans,註意 ans 的初值為 1,因為第一次搬動要算作一次搬動,但這一次沒有與任何路徑重疊。

模擬做的直接超時了......

代碼如下:

技術分享圖片
 1 int t,n,ans,mp[405];
 2 bool f;
 3 struct node
 4 {
 5     int from,to,len;
 6 }p[205];
 7 bool cmp(node a,node b)
 8 {
 9     return a.len!=b.len?a.len<b.len:a.from<b.from;
10 }
11 int main()
12 {
13     scanf("%d",&t);
14     while(t--)
15     {
16         scanf("%d"
,&n); 17 ans = 1; 18 memset(mp,0,sizeof(mp)); 19 for(int i = 0; i < n; ++i) 20 { 21 scanf("%d%d",&p[i].from,&p[i].to); 22 p[i].len = p[i].to-p[i].from; 23 } 24 sort(p,p+n,cmp); 25 for(int i = 0; i < n; ++i)
26 { 27 f = true; 28 for(int j = p[i].from; j <= p[i].to; ++j) 29 { 30 if(mp[j]) 31 { 32 ans++; 33 fill(mp+p[i].from,mp+p[i].to,-1); 34 f = false; 35 break; 36 } 37 } 38 if(f) fill(mp+p[i].from,mp+p[i].to,-1); 39 } 40 printf("%d\n",ans*10); 41 } 42 return 0; 43 }
View Code

看了其他人的做法,才知道不應該把房間看作排列在一條線段上的點,而是如題目中描述的那樣排在一對平行線上:

技術分享圖片

這樣將房間前的位置用一個長 200 的一維數組來存,在每次的路徑的每一個位置上增加 1,這個數組中的最大值即為搬動次數。如圖示的情況即為:1,2,2,0,...

技術分享圖片

搬動次數即為 2 次。

代碼如下:

技術分享圖片
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5      int t,n,from,to,ans;
 6      int cnt[204],tmp;
 7      scanf("%d",&t);
 8      while(t--)
 9      {
10         scanf("%d",&n);
11         memset(cnt,0,sizeof(cnt));
12         ans = 0;
13         for(int i = 1; i <= n; ++i)
14         {
15             scanf("%d%d",&from,&to);
16             if(from > to)
17             {
18                 tmp = from;
19                 from = to;
20                 to = tmp;
21             }
22             for(int j = (from+1)/2; j <= (to+1)/2; ++j)
23                 cnt[j]++;
24         }
25         for(int i = 1; i <= 201; ++i)
26             if(ans<cnt[i]) ans = cnt[i];
27         printf("%d\n",ans*10);
28      }
29      return 0;
30 }
View Code

另外還知道了一點,在交換兩變量的值時,用位運算的方法更快:

如 temp = a; a = b; b = temp;

用位運算實現:a = a^b; b = a^b; a = a^b;

本題中由於沒註意到有可能搬動是從房間號較大的房間搬向房間號較小的房間,還 wa 了......

解決辦法就是再加一步如果是這種情況就交換兩房間的號碼,即還是從小到大的順序,這裏直接交換的結果是 15ms,用位運算交換的結果是 0ms.

以後就要改用這種位運算交換的方法了。

特向這篇博客的作者致謝:https://www.cnblogs.com/cchun/archive/2011/05/14/2520076.html

HDU 1050(搬椅子 數學)