码迷,mamicode.com
首页 > 其他好文 > 详细

Ants POJ - 1852 弹性碰撞+模拟

时间:2020-02-10 22:19:16      阅读:94      评论:0      收藏:0      [点我收藏+]

标签:lock   with   code   端点   space   else   reset   name   -o   

题目 https://vjudge.net/problem/POJ-1852

题意:在一个固定长度的木条上面有n只蚂蚁,每个蚂蚁的速度一样,方向任意(可由自己决定初始方向),每只蚂蚁碰头后会朝相反反向前进,问所有蚂蚁都从木条上掉下去(走到左右端点处)的最短和最长时间是多少?

这篇博客讲的挺好 https://www.cnblogs.com/zhenghao2/p/6446065.html

思路:

1.这道题一开始思考最大时间的时候,可能会想,如果在木条上面一直碰头变换位置,那么时间一定会是最大的?当然不是,而且也很难编程;正解应该是实际上每只蚂蚁碰头后,可以把它当成依然沿原始方向前进,你想啊,,碰头后就是继承了另一只蚂蚁的方向,所以相当于没有碰头。可以自己用一段长度为3的木条模拟(比较容易模拟)

所以,我们只需要找到一只离端点最远的那只蚂蚁,就是最长时间了

 

2.什么情况下时间最短,将木条平均分成两段,在左边那段就从左端点下去,方向全部向左,右边同理,就可以实现时间最短

往近的端点走);代码实现中先在里面的min比较该蚂蚁从哪个端点走更近,之后在外面判断离两段木条中最远的那只蚂蚁在哪

代码有个细节注意一下,最里面的max和min比较的是距离左端点近还是右端点近,为什么求最短时间最外层要用

max?因为最远的那只决定了最短所需总时间

技术图片
 1 #include<iostream>
 2 #include<cstring>
 3 #include<math.h>
 4 #include<stdlib.h>
 5 #include<cstring>
 6 #include<cstdio>
 7 #include<utility>
 8 #include<algorithm>
 9 #include<map>
10 using namespace std;
11 typedef long long ll; 
12 inline int read(){
13     int X=0,w=0;char ch=0;
14     while(!isdigit(ch)){w|=ch==-;ch=getchar();}
15     while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
16     return w?-X:X;
17 }
18 /*------------------------------------------------------------------------*/
19 const int maxn=0x3f3f3f3f; 
20 int main( )
21 {    
22     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
23     //freopen("a.txt","r",stdin);
24     //freopen("a.txt","w",stdout);
25     int t;
26     cin>>t;
27     while(t--){
28         
29         int len,n;
30         cin>>len>>n;
31         int maxx=0,minn=0;
32         while(n--){
33             
34             int now;
35             //now=read();
36             cin>>now;
37             maxx=max(maxx,max(now,len-now));
38             minn=max(minn,min(now,len-now));
39             
40         }
41         cout<<minn<<" "<<maxx<<endl;
42     }
43     
44     return 0;
45 }
View Code

蓝桥杯有一道类似的题目:蚂蚁感冒

https://www.dotcpp.com/oj/problem1454.html

?技术图片技术图片??

?技术图片技术图片??

这道题目可分为两种情况模拟,若初始感冒蚂蚁方向向左,则左边与他相反方向的蚂蚁必定被感染,此时初始感冒蚂蚁调转方向到右边,右边与他同方向的蚂蚁也必定被感染
右边同理

那么为什么分两种情况讨论?
这就涉及到了代码实现的一些细节了,当我们判断初始感冒蚂蚁的方向向左时,我先考虑左边那一侧,初始感冒蚂蚁的方向向右时,先考虑右边那一侧,细节问题注意一下就好了

技术图片
 1 #include<iostream>
 2 #include<cstring>
 3 #include<math.h>
 4 #include<stdlib.h>
 5 #include<cstring>
 6 #include<cstdio>
 7 #include<utility>
 8 #include<algorithm>
 9 #include<map>
10 using namespace std;
11 typedef long long ll; 
12 inline int read(){
13     int X=0,w=0;char ch=0;
14     while(!isdigit(ch)){w|=ch==-;ch=getchar();}
15     while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
16     return w?-X:X;
17 }
18 /*------------------------------------------------------------------------*/
19 
20 struct node{
21     int dir,sum;//方向和位置 
22     int flag;//是否感冒 
23 }star[100];
24 const int maxn=1005; 
25 void init(int n){
26     for(int i=1;i<=n;++i){
27         star[i].flag=0;
28         star[i].dir=0;
29         star[i].sum=0;   
30     }
31 }
32 bool cmp(node a,node b){
33     return a.sum<b.sum;
34 }
35 int main( )
36 {    
37     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
38     //freopen("a.txt","r",stdin);
39     //freopen("a.txt","w",stdout);
40     int n;
41     cin>>n;
42     init(n);
43     for(int i=1;i<=n;++i){
44         int now; 
45         cin>>now;
46         if(i==1)star[i].flag=1; 
47         if(now<0)star[i].dir=-1,star[i].sum=-now;
48         else star[i].sum=now,star[i].dir=1;    
49     }
50     sort(star+1,star+1+n,cmp);
51     int pos;
52     for(int i=1;i<=n;++i){
53         if(star[i].flag==1){
54             pos=i;
55             break;
56         }
57     }
58     /*for(int i=1;i<=n;++i){
59         cout<<star[i].sum<<" ";
60     }*/
61     
62     int ans=1;
63     if(star[pos].dir==1){//往右 
64         for(int i=pos+1;i<=n;++i){
65         if(star[i].dir+star[pos].dir==0)
66         ans++;
67         }
68         for(int i=1;i<=pos-1;++i){
69             if(star[i].dir==star[pos].dir)
70             ans++;
71         }
72         cout<<ans;
73     }
74     else{
75         for(int i=1;i<=pos-1;++i){
76         if(star[i].dir+star[pos].dir==0)
77         ans++;
78         }
79         for(int i=pos+1;i<=n;++i){
80             if(star[i].dir==star[pos].dir)
81             ans++;
82         }
83         cout<<ans;
84     } 
85     return 0;
86 }
View Code

 

Ants POJ - 1852 弹性碰撞+模拟

标签:lock   with   code   端点   space   else   reset   name   -o   

原文地址:https://www.cnblogs.com/simaomao/p/12293039.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!