[USACO13OPEN]豪华游船Luxury River Cruise

题目描述

农民约翰带着Bessie和奶牛在邮轮上!他们在网格上的N条河流航行(1≤N≤1000)标记为1到N,一开始他们在开始在河口1。每一个港口都有两条河流直通,直接通往其他港口,河流只能通过一条路航行。

在每一个港口,导游选择左边的河或右边的河向下航行,但他们不断重复相同的选择一遍又一遍。更具体地说,导游选择了一个m方向(1 < =m= 500),每一个向左或向右,并重复它K次(1 < = K = 1000000000)。Bessie认为她是在兜圈子,帮她找出结束的位置!

输入输出格式

输入格式:

 

* Line 1: Three space-separated integers N, M, and K.

* Lines 2..N+1: Line i+1 has two space-separated integers,

representing the number of the ports that port i's left and right rivers lead to, respectively.

* Line N+2: M space-separated characters, either 'L' or 'R'. 'L' represents a choice of 'left' and 'R' represents a choice of 'right'.

 

输出格式:

 

* Line 1: A single integer giving the number of the port where Bessie's cruise ends.

 

输入输出样例

输入样例#1: 

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

输出样例#1: 

4 

说明

The port numbers are arranged clockwise in a circle, with 'L' being a clockwise rotation and 'R' being a counterclockwise rotation. The sequence taken is LLRLLRLLR.

After the first iteration of the sequence of directions, Bessie is at port 2 (1 -> 2 -> 3 -> 2); after the second, she is at port 3 (2 -> 3 -> 4 -> 3), and at the end she is at port 4 (3 -> 4 -> 1 -> 4).

感谢 @ SilverWolf 提供翻译

 

输入的意思是

第一行 n,m,k 不多说

第二行的两个数表示当前港口左边能到达哪一个港口,右边能到达哪一个港口

然后就给出一波操作,重复做这一波操作k次 , 求重复完所有的操作最后停留在哪个港口上

 

这是模拟题(废话) 

60分打法就是直接暴力

100分打法如下

首先一直模拟船的行驶,记录每一次操作的开始点,如果某一次操作到达了被标记过的点,说明船会在这一个点开始重复路线

这种模拟最多1000次(因为只有一千个港口)吗,然后就可以开始重复了

我们先到哪个会重复行驶的点,然后对k取模,在模拟一次就的出结果时间最多O(n^2)

代码

#include <iostream>
#include <cstring>

using namespace std ;

const int N = 1100 ;
int n , m , k , a[N] , map[N][2] ;
int flag[N] ;
char st[3];

int main() {
	cin >> n >> m >> k ;
	for ( int i = 1 ; i <= n ; i ++ )
		cin >> map[i][0] >> map[i][1] ;
	for ( int i = 1 ; i <= m ; i ++ ) 
		cin >> st , a[i] = ( st[0] == 'R' ? 1 : 0 ) ;
	memset ( flag , 0 , sizeof( flag ) ) ;
	int now = 1 , cnt = 0 ;
	while ( flag[now] == 0 ) {
		flag[now] = ++ cnt ;
		for ( int i = 1 ; i <= m ; i ++ ) now = map[now][a[i]] ;
	}
	if ( k < flag[now] ) { //如果重复次数没有达到重复的点,就直接模拟结果 
		now = 1 ;
		for ( int ki = 1 ; ki <= k ; ki ++ ) 
			for ( int i = 1 ; i <= m ; i ++ ) 
				now = map[now][a[i]] ; 
		cout << now << endl ;
	}
	else { //否则就取模以后在模拟结果 
		k = k - flag[now] + 1 ; //先减掉不重复的路 
		k = k % ( cnt - flag[now] +1 ) ; //对k取模 
		for ( int ki = 1 ; ki <= k ; ki ++ )  //模拟路线 
			for ( int i = 1 ; i <= m ; i ++ ) 
				now = map[now][a[i]] ;
		cout << now << endl ; //输出 
	}
	return 0 ;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值