京东笔试-站队

题目描述
									

有一条很长的队伍,队伍里面一共有n个人。所有的人分为三类:警察,小偷和普通人。将队伍里面的人从前到后由1到n编号,编号为i的人与编号为j的人的距离为i与j之差的绝对值。

每一个警察有一个能力值x,表示他能够监视与他距离不超过x的所有人,小偷被警察发现当且仅当他被一个或多个警察监视到。你知道在整条队伍中,一共有多少个小偷会被警察发现吗?

输入

输入有两行,第一行一个数n(1<=n<=100000),接下来一行有一个长度为n的字符串,依次表示队伍中的每一个人。如果某一位是1-9的某个数字x,表示这一位是一个能力值为x的警察;如果某一位是字符X表示这一位是小偷;如果某一位是字符#表示这是一个普通人。输入保证不会出现其它字符。

样例输入

9

X1X#2X#XX

输出

输出一个数,整条队伍中被警察发现的小偷总数。 

样例输出

3


思路在代码中给出。

package JD;

import java.util.Scanner;

public class duilie {
	public static void main(String[] rags) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			int n = sc.nextInt();
			String str = sc.next();
			System.out.println(findTheif(str));
		}
	}
    /*
     * 简单思路:当发现一个警察时,就将他监视范围内的小偷抓出来,并将小偷替换成普通人,继续向后遍历寻找警察
     */
	public static int findThrif(String str) {
		char[] ch = str.toCharArray();
		int count = 0;
		int len = ch.length;
		for (int i = 0; i < len; i++) {
			if (ch[i] - '0' >= 0 && ch[i] - '0' <= 9) {
				for (int j = i; j < len && j <= i + (ch[i] - '0'); j++) {
					if (ch[j] == 'X') {
						count++;
						ch[j] = '#';
					}
				}

				for (int j = i; j >= 0 && j >= i - (ch[i] - '0'); j--) {
					if (ch[j] == 'X') {
						count++;
						ch[j] = '#';
					}
				}
			}
		}
		return count;
	}
         //方法二:
	//分别记录小偷在队列中出现的位置(T[i] = j,表示第i个小偷在队列中的位置为j),
	//以及警察所能监视的区域(P[k-n]~P[k+n] == 1即所监视区域全为1),然后判断P[T[i]] ==1,
	//如果为1,该位置上的小偷会被抓住,
	public static int findTheif(String str) {
		int count = 0;
		if (str == null)
			return count;
		char[] ch = str.toCharArray();
		int n = ch.length;
		int[] T = new int[n + 1];
		int[] P = new int[n];
		int m = 1;
		for (int i = 0; i < n; i++) {

			if (ch[i] == 'X') {
				T[m++] = i;
			} else {
				T[m++] = -1;
			}
		}
		for (int i = 0; i < n; i++) {
			if ((ch[i] - '0') >= 0 && (ch[i] - '0') <= 9) {
				for (int j = i + 1; j < n && j <= i + (ch[i] - '0'); j++) {
					P[j] = 1;
				}
				for (int j = i - 1; j >= 0 && j >= (i - (ch[i] - '0')); j--) {
					P[j] = 1;
				}
			}
		}

		int k = 1;
		while (k < T.length) {
			if (T[k] != -1) {
				if (P[T[k]] == 1) {
					count++;
				}
			}
			k++;
		}
		return count;
	}
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值