标签:
最近做了几个蚂蚁问题,还蛮有趣的。。。。。
蚂蚁问题第一弹:poj 1852 Ants:
Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 12214 | Accepted: 5366 |
Description
Input
Output
Sample Input
2 10 3 2 6 7 214 7 11 12 7 13 176 23 191
Sample Output
4 8 38 207
题意:一根木棒上有很多蚂蚁,给出这些蚂蚁初始时离木棒左端的距离,当然这些蚂蚁一开始是向左爬还是向右爬是未知的。由于木棒很细,因此如果两只蚂蚁碰到了它们会各自掉头继续爬,问这些蚂蚁全都掉下去最少和最多需要多少时间。
题解:首先可以确定两只蚂蚁相撞之后速度大小不变,只是换了一个方向而已,而且我们要求的是时间大小,具体是哪一只没差。那么可以把每一只蚂蚁相撞的情况看成是穿过。那么这一只蚂蚁要走的路的长短取决于方向即:L(木棒长)-X(初始位置)或者 X。
#include <iostream> #include <cstdio> using namespace std; int main() { int T,L,n; cin>>T; while(T--) { int temp,cc,Min=-1e9,Max=-1e9; cin>>L>>n; for(int i=0;i<n;i++) { cin>>temp; cc=min(L-temp,temp); Min=max(cc,Min); cc=max(L-temp,temp); Max=max(cc,Max); } cout<<Min<<" "<<Max<<endl; } return 0; }
蚂蚁问题第二弹:UVA 10881 Piotr‘s Ants
一根长度为L厘米的木棍上有n只蚂蚁,每只蚂蚁要么往左爬要么往右爬,速度为1cm/s。当两只蚂蚁相遇时,二者同时掉头(掉头时间忽略不计)。给出每只蚂蚁的初始位置和朝向,计算T秒之后蚂蚁的位置。
输入第一行为数据组数。每组第一行为三个整数L,T,n(n≤10 000);以下n行描述一只蚂蚁的初始位置,其中,整数x为蚂蚁距左端的距离(单位:厘米),字母表示初始朝向(L向左,R向右)。
对于每组数据,输出n(Case #n:),按输入顺序输出每只蚂蚁的位置和朝向(Turning表示正在碰撞)。在T秒之前已经掉落的蚂蚁(正好爬到边缘不算)输出Fell off
样例输入:
2
10 1 4
1 R 5 R 3 L 10 R
10 2 3
4 R 5 L 8 R
样例输出:
Case #1:
2 Turning
6 R
2 Turning
Fell off
Case #2:
3 L
6 R
10 R
题意:同样是蚂蚁爬杆问题,不过这道题相比上一道题增加了一些难度,他会告诉你蚂蚁的初始爬行方向,要你求出T秒后蚂蚁的位置以及爬行方向
思路:首先我们可以知道,由于存在这么一个条件:两只蚂蚁如果碰头了那么它们就会反向掉头,又因为所有的蚂蚁速度都是相同的大小,那么除了那些掉下去的蚂蚁,所有的蚂蚁位置都是不变的,比如说1号蚂蚁在2号蚂蚁的左边,那么不论它们走多久,1号蚂蚁都不会走到2号蚂蚁的右边。因此我们可以对所有蚂蚁的位置进行一次排序,那么在行走前和行走后蚂蚁们的相对位置都是不变的,就可以解决掉判断是否是turnning这种情况了,然后就是和上道题一样的解法,可以把相撞的情况看成是穿过。。。。
#include <iostream> #include <algorithm> #include <cstdio> using namespace std; const int maxn=1e4+10; struct node { int id,p,d; bool operator < (const node &another) const { return p<another.p; } }a[maxn],c[maxn]; int idx[maxn]; int main() { int T,ca=1; cin>>T; while(T--) { int l,t,n; cin>>l>>t>>n; for(int i=0;i<n;i++) { char ch; scanf("%d %c",&a[i].p,&ch); switch(ch) { case ‘R‘:a[i].d=1;break; case ‘L‘:a[i].d=-1;break; } c[i].p=a[i].p; c[i].id=i; a[i].p+=t*a[i].d; if(a[i].p<0||a[i].p>l) a[i].d=0; } sort(c,c+n); sort(a,a+n); for(int i=0;i<n-1;i++) { if(a[i].p==a[i+1].p) a[i].d=a[i+1].d=2; } for(int i=0;i<n;i++) idx[c[i].id]=i; sort(idx,idx+n); cout<<"Case #"<<ca++<<":"<<endl; for(int j=0;j<n;j++) { int i=idx[j]; switch(a[i].d) { case -1:cout<<a[i].p<<" "<<"L"<<endl;break; case 0:cout<<"Fell off"<<endl;break; case 1:cout<<a[i].p<<" "<<"R"<<endl;break; case 2:cout<<a[i].p<<" "<<"Turning"<<endl;break; } } puts(""); } return 0; }
蚂蚁问题第三弹:NYOJ 990
长100厘米的细长直杆子上有n只蚂蚁。它们的头有的朝左,有的朝右。 每只蚂蚁都只能沿着杆子向前爬,速度是1厘米/秒。 当两只蚂蚁碰面时,它们会同时掉头往相反的方向爬行。 这些蚂蚁中,有1只蚂蚁感冒了。并且在和其它蚂蚁碰面时,会把感冒传染给碰到的蚂蚁。 请你计算,当所有蚂蚁都爬离杆子时,有多少只蚂蚁患上了感冒。
第一行输入一个整数n (1 < n < 50), 表示蚂蚁的总数。
接着的一行是n个用空格分开的整数 Xi (-100 < Xi < 100), Xi的绝对值,表示蚂蚁离开杆子左边端点的距离。正值表示头朝右,负值表示头朝左,数据中不会出现0值,也不会出现两只蚂蚁占用同一位置。其中,第一个数据代表的蚂蚁感冒了。
要求输出1个整数,表示最后感冒蚂蚁的数目。
#include <iostream> #include <algorithm> #include <cmath> #include <cstdio> using namespace std; int sum1,sum2; void judge(int a1,int a2) { if((a2>0)&&(abs(a1)>abs(a2))) sum1++; if((a2<0)&&(abs(a1)<abs(a2))) sum2++; } int main() { int n; while(cin>>n) { int t,cc; cin>>t; sum1=0;sum2=0; for(int i=0;i<n-1;i++) { cin>>cc; judge(t,cc); } if(t<0&&sum1==0||t>0&&sum2==0) cout<<1<<endl; else cout<<sum1+sum2+1<<endl; } return 0; }
标签:
原文地址:http://www.cnblogs.com/zsyacm666666/p/4779513.html