USACO 2012 December Contest, Bronze Problem 1. Meet and Greet (模拟)

原题:http://www.usaco.org/index.php?page=viewproblem2&cpid=205#

Problem 1: Meet and Greet [Brian Dean, 2012]As is commonly known, cows are very socially polite creatures: any time twocows meet after being apart, they greet each-other with a friendly "moo".Bessie the cow and her friend, Elsie, are walking around on a longpath on Farmer John's farm. For all practical purposes, we can thinkof this path as a one-dimensional number line. Bessie and Elsie bothstart at the origin, and they both then begin walking around atidentical speeds for some amount of time. Given a description of themovements taken by each cow, please determine the number of "moos"exchanged. Bessie and Elsie can stop moving at different points in time, andneither cow will travel for more than 1,000,000 units of time.

PROBLEM NAME: greetings

INPUT FORMAT:

* Line 1: Two space-separated integers, B (1 <= B <= 50,000) and E(1 <= E <= 50,000).

* Lines 2..1+B: These B lines describe Bessie's movements. Each line contains a positive integer followed by either "L"or"R",indicating the distance Bessie moves in a direction that is either left or right.  

* Lines 2+B..1+B+E: These E lines describe Elsie's movements. Each line contains a positive integer followed by either "L" or "R", indicating the distance Elsie moves in a direction that is either left or right.

SAMPLE INPUT (file greetings.in):

4 5
3 L
5 R
1 L
2 R
4 R
1 L
3 L
4 R
2 L

INPUT DETAILS:

Bessie moves left for 3 units of time, then right for 5 units of time, thenleft for 1 unit of time, and finally right for 2 units of time; she thenstands still. Elsie moves right for 4 units of time, then left for 4 unitsof time, then right for 4 units of time, then left for 2 units of time; shethen stands still.

OUTPUT FORMAT:

* Line 1: An integer specifying the number of "moos" exchanged by the two cows. Their initial shared starting position at the origin does not cause a "moo".

SAMPLE OUTPUT (file greetings.out):

3O

UTPUT DETAILS:

Bessie and Elsie meet after being temporarily apart at time 7, time 9, andtime 13.

这个USACO跟那个USACO不知道什么区别。

题意:有两头牛Bessie和Elsie,给出两个正整数B和E,分别代表Bessie和Elsie的移动情况个数,然后每一行给出一个正整数dt和一个方向dir,代表牛向左或者向右走了dt个单位时间。牛移动的速度是一样的,自从它们从同一个起点分离后一见面就会发出“moo”的声音,问它们总共发了几次声音。

算法思路:对每一头牛的某个时刻的移动情况进行记录,然后按时间从小到大排序。然后遍历比较。

官方题解:http://www.usaco.org/current/data/sol_greetings.html

Solution Notes (Jonathan Paulson): This is a simulation problem, and the constraint that the cows only travel for 10^6 seconds makes it pretty straightforward. You can just write down for each cow where it is at each second as you read the input, and then count the number of times T when their positions at T were different but their positions at T+1 were the same.

The problem is still efficiently solvable if the times are much larger (say, up to 10^12) but the number of instructions is still small (say, 100,000). Then the solution is a version of coordinate compression (which also makes an appearance in "crazy fences"); the only "interesting times" are when a cows speed changes, and there are at most 200,000 of these (each instruction causes an increase and then decrease in speed; actually, since the start of one instruction and the beginning of another overlap, the real number is more like 100,000 but this isn't important). To simplify implementation of this idea, it is useful to keep track of Bessie's movement relative to Elsie, instead of their absolute positions. Then a moo occurs when Bessie passes 0. Now that time is divided up into ~100,000 intervals of constant speed, it is easy to compute the change in position due to each time interval, and keep track of the number of times Bessie passes 0.

实现代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <climits>
using namespace std;

const int INF=0x3f3f3f3f;
#define Bessie 0
#define Elsie 1
struct KeyPoint
{
	int t,cow,newdir;
	KeyPoint(int t,int cow,int newdir):t(t),cow(cow),newdir(newdir){}
	bool operator < (KeyPoint const& x) const
	{
		return t<x.t;
	}
};
vector<KeyPoint> keyPoints;
//读取每一头牛的一系列移动
int read_keyPoints(int n,int cow)
{
	int t=0;
	int initdir;
	for(int i=0;i<n;i++)
	{
		int dt;
		char c;
		int dir;
		scanf("%d %c",&dt,&c);
		dir=(c=='L' ? -1:1);
		if(t==0)
		{
			initdir=dir;
		}
		else
		{
			keyPoints.push_back(KeyPoint(t,cow,dir));
		}
		//记录时刻
		t+=dt;
	}
	keyPoints.push_back(KeyPoint(t,cow,0));
	return initdir;
}

int main()
{
	int B,E;
	keyPoints.clear();
	freopen("greetings.in","r",stdin);
    freopen("greetings.out","w",stdout);
	scanf("%d%d",&B,&E);
	//初始化每一头牛一开始移动方向
	int dir0=read_keyPoints(B,Bessie);
	int dir1=read_keyPoints(E,Elsie);
	//对时刻进行排序
	sort(keyPoints.begin(),keyPoints.end());
	//初始化时刻,每头牛的位置
	int t=0;
	int x0=0;
	int x1=0;
	//牛的“moos"次数
	int moos=0;
	for(int i=0;i<keyPoints.size();i++)
	{
		//时间来到new_t时刻
		int new_t=keyPoints[i].t;
		//牛来到的新位置
		int new_x0=x0+(new_t-t)*dir0;
		int new_x1=x1+(new_t-t)*dir1;
		//判断两牛是否在(t,new_t]发出”moos"叫声。
        //如果两牛发出声音,它们上一次一定没有发“moos",然后2种情况:一种在new_t见面,另一种在(t,new_t)见面,异或处理表示二者只有一个成立
		if(x0!=x1&&((new_x0==new_x1)||((x0<x1)^(new_x0<new_x1))))moos++;
		//更新时刻和方向
		t=new_t;
		x0=new_x0,
		x1=new_x1;
		if(keyPoints[i].cow==Bessie)dir0=keyPoints[i].newdir;
		else dir1=keyPoints[i].newdir;
	}
	printf("%d\n",moos);
	return 0;
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值