湖南大學第十四屆ACM程式設計大賽 A-AFei Loves Magic
連結:https://ac.nowcoder.com/acm/contest/338/A
來源:牛客網
時間限制:C/C++ 1秒,其他語言2秒
空間限制:C/C++ 131072K,其他語言262144K
64bit IO Format: %lld
題目描述
AFei is a trainee magician who likes to study various magical materials. Today, he came to the forest to find rare materials. He was so lucky that he found a piece of high-level magic stone. He knew that this stone always appeared in the pile, so there must be more nearby. Then he went deeper.
As expected, he found many magic stones. These stones were arranged in a row. Just as he was ready to pick up one, a magical circle was triggered. He was petrified and the stones began to move. As mentioned above, the stones were lined up. Now, some stones moved to one end of the line and the other stones moved to the other end. Stones would not change direction of movement unless they collided with other stones. Collision meant that two stones moved to the same position, and then the directions of the two stones would both change. Whether or not a collision occured, the speed was always 1 m/s. Stone would disappear when it reached one of the ends.
AFei knew that the magical circle would disappear after t seconds. It meant that after t seconds, he could move and the stones would return to immobility. This also meant that AFei would get those stones. He wondered how many magic stones he could get in the end, including the first one he got when he came to the forest.
輸入描述:
The first line contains three integers n, L, t (0≤n≤1000000, 2≤L≤1000000000, 0<=t<=1000000) − the number of stones on the line is n,the length of the line is L meter, and the magic circle will disappear after t seconds. The following n lines contain description of magic stones on the line. Each i-th of these lines contains two space-separated integers x[i] and d[i] (0<x[i]<L, d[i]∈{1,2} for i<=n), which stand for initial position and direction of motion(1 means from 0 to L, 2 means from L to 0.).
輸出描述:
Output a number indicating the amount of the magic stones that AFei will eventually be able to obtain.
示例1
輸入
0 10000 3
輸出
1
說明
There is no magic stone on the line, but AFei has got one when he came to the forest.
示例2
輸入
4 10 6
1 1
5 2
6 1
9 2
輸出
3
說明
The stones are A(1,1), B(5,2), C(6,1), D(9,2).
After 1s, they become A(2,1), B(4,2), C(7,1), D(8,2);
After 2s, they become A(3,2), B(3,1), C(7,2), D(8,1);
After 3s, they become A(2,2), B(4,1), C(6,2), D(9,1);
After 4s, they become A(1,2), B(5,2), C(5,1), D reach L and disappears;
After 5s, they become A reach 0 and disappears, B(4, 2), C(6,1), D disappeared;
After 6s, they become A disappeared, B(3, 2), C(7, 1), D disappeared.
AFei finially gets the first one, B and C.
備註:
1,Input guarantees that there will not be two magic stones in one location.
2,If stone A and stone B are located at 4 and 5, respectively, and A's direction is 1, B's direction is 2. Then next second, the position of the two stones have not changed, but they have gone in the opposite direction.
題目大意:
AFei是一名見習魔術師,他喜歡學習各種魔法材料。今天,他來到森林尋找稀有材料。他很幸運,找到了一塊高階魔石。他知道這石頭總是出現在那堆石頭裡,所以附近一定有更多的石頭。然後他走得更深了。
正如所料,他發現了許多魔法石。這些石頭排列成一排。就在他準備接電話的時候,一個神奇的圓圈被觸發了。他被石化了,石頭開始移動。如上所述,這些石頭排列整齊。現在,一些石頭移到了線的一端,另一些石頭移到了線的另一端。除非石頭與其他石頭相撞,否則它們不會改變運動方向。碰撞意味著兩塊石頭移動到相同的位置,然後兩塊石頭的方向都會改變。無論是否發生碰撞,速度始終為1 m/s。當石頭到達其中一端時,它將消失。
阿菲知道魔法圈會在T秒後消失。這意味著T秒後,他可以移動,石頭將恢復靜止。這也意味著阿菲會得到那些石頭。他想知道到底能得到多少塊魔法石,包括他來到森林時得到的第一塊。
第一行包含三個整數n,l,t(0≤n≤1000000,2≤l≤100000000,0<=t<=1000000)-行上的石頭數為n,行的長度為l米,T秒後魔法圓消失。
下面的n行包含對線上魔法石的描述。這些行中的每一個i-th都包含兩個空格分隔的整數x[i]和d[i](0<x[i]<l,d[i]1,2表示i<=n),表示初始位置和運動方向(1表示從0到l,2表示從l到0)。
輸出一個數字,指示AFEI最終能夠獲得的魔法石數量。
分析:本題的難點主要在於碰撞後的情況,因為碰撞後兩塊石頭的方向都改變了,但有一點是不變的,即所有的石頭都是相同的,我們可以把碰撞看作是交換,或者可以說是兩塊石頭“擦肩而過”,因為兩塊相同的石頭碰撞後改變方向與兩塊相同的石頭迎面路過沒什麼區別。可以等效看待。這樣問題就簡化了。每次輸入石頭的位置和運動方向後只需考慮這一個石頭在規定時間內是否會運動到起點或終點,如果成立那麼這塊石頭就作廢了,作廢數量+1。最後用總數量減去作廢數量再+1借有效石頭數量
#include<iostream>
using namespace std;
long long a[1000005],b[1000005];//注意一定要把陣列開為全域性變數開到1e6,否則判題機會發生執行錯誤
int main()
{
long long n,l,t,sum=0;
cin>>n>>l>>t;//輸入石頭數,行的長度,規定時間
for(int i=1;i<=n;i++)
{
cin>>a[i]>>b[i];//輸入單個石頭的位置以及運動方向
if(b[i]==1&&a[i]+t>=l)//判斷單個石頭是否在規定時間內會運動到終點,如果成立,則該石頭作廢
sum++;
else if(b[i]==2&&a[i]-t<=0)
sum++; //或者判斷單個石頭是否在規定時間內會運動到起點,如果成立,則該石頭作廢
}
cout<<n-sum+1<<endl;//輸出總數減去作廢數+1即為有效石頭數
}