UVa719 - Glass Beads(最小表示法)

Glass Beads 

Once upon a time there was a famous actress. As you may expect, she playedmostly Antique Comedies most of all. All the people loved her. But she was notinterested in the crowds. Her big hobby were beads of any kind. Many beadmakers were working for her and they manufactured new necklaces andbracelets every day. One day she called her mainInspector of BeadMakers (IBM) and told him she wanted a very long and specialnecklace.


The necklace should be made of glass beads of different sizes connectedto each other but without any thread running through the beads, so thatmeans the beads can be disconnected at any point. The actress chose thesuccession of beads she wants to have and the IBM promised to make thenecklace. But then he realized a problem. The joint between two neighbouringbeads is not very robust so it is possible that the necklace will get tornby its own weight. The situation becomes even worse when the necklace isdisjoined. Moreover, the point of disconnection is very important. If thereare small beads at the beginning, the possibility of tearing is much higherthan if there were large beads. IBM wants to test the robustness of anecklace so he needs a program that will be able to determine the worstpossible point of disjoining the beads.


The description of the necklace is a string $A =a_1a_2 \dots a_m$specifying sizes of the particular beads, where the last characteram is considered to precede character a1 in circular fashion.


The disjoint point i is said to be worse than the disjointpoint j if and only if the string$a_ia_{i+1} \dots a_na_1 \dots a_{i-1}$is lexicografically smaller than the string$a_ja_{j+1} \dots a_na_1 \dots a_{j-1}$.String$a_1a_2 \dots a_n$is lexicografically smaller than the string$b_1b_2 \dots b_n$if and only if there exists an integer $i, i \le n$,so thataj=bj, for each$j, 1 \le j < i$andai < bi.

Input 

The input consists of N cases. The first line of the inputcontains only positive integerN. Then follow the cases. Each case consists of exactly one line containing necklace description.Maximal length of each description is 10000 characters. Each bead is represented by a lower-case character of the english alphabet (a-z), where $a < b \dots < z$.

Output 

For each case, print exactly one line containingonly one integer - number of thebead which is the first at the worst possible disjoining, i.e. suchi, that the stringA[i] is lexicographically smallestamong all the n possible disjoinings of a necklace. If there aremore than one solution, print the one with the lowesti.

Sample Input 

4
helloworld
amandamanda
dontcallmebfu
aaabaaa

Sample Output 

10
11
6
5
最小表示法

初始时,i = 0, j = 1, k = 0, 分别以i,j为起始点,顺着i,j比较直到s[i + k]不等于 s[j + k],有两种情况:

1.s[i + k] > s[j + k], j不变,i取j + 1,i + k + 1中的最大值

2.s[i + k] < s[j + k],i不变,j取i + 1, j + k + 1中的最大值

import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main 
{
	private static final boolean DEBUG = false;
	private BufferedReader cin;
	private PrintWriter cout;
	private StreamTokenizer tokenizer;
	private String s;
	
	
	public void init() 
	{
		try {
			if (DEBUG) {
				cin = new BufferedReader(new InputStreamReader(
						new FileInputStream("d:\\OJ\\uva_in.txt")));
			} else {
				cin = new BufferedReader(new InputStreamReader(System.in));
			}
			cout = new PrintWriter(new OutputStreamWriter(System.out));
			tokenizer = new StreamTokenizer(cin);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public String next()
	{ 
		try {
			tokenizer.nextToken();
			if (tokenizer.ttype == StreamTokenizer.TT_EOF) return null;
			else if (tokenizer.ttype == StreamTokenizer.TT_NUMBER) return String.valueOf((int)tokenizer.nval);
			else return tokenizer.sval;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public boolean input() 
	{
		s = next();
		return true;
	}

	
	
	public void solve() 
	{
		int len = s.length();
		int p1 = 0, p2 = 1, k = 0;
		while (p1 < len && p2 < len) {
			while (k < len && s.charAt((p1 + k) % len) == s.charAt((p2 + k) % len)) k++;
			if (k == len) break;
			
			if (s.charAt((p1 + k) % len) > s.charAt((p2 + k) % len)) {
				p1 = Math.max(p2 + 1, p1 + k + 1);
			} else {
				p2 = Math.max(p1 + 1, p2 + k + 1);
			}
			
			k = 0;
		}
		
		cout.println(Math.min(p1, p2) + 1);
		cout.flush();
	}

	public static void main(String[] args) 
	{
		Main solver = new Main();
		solver.init();
		
		int t = Integer.parseInt(solver.next());
		while (t-- > 0) {
			solver.input();
			solver.solve();
		}
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值