Tinkoff Challenge - Elimination Round总结

123 篇文章 0 订阅
69 篇文章 0 订阅
A. Oleg and shares
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Oleg the bank client checks share prices every day. There are n share prices he is interested in. Today he observed that each second exactly one of these prices decreases by k rubles (note that each second exactly one price changes, but at different seconds different prices can change). Prices can become negative. Oleg found this process interesting, and he asked Igor the financial analyst, what is the minimum time needed for all n prices to become equal, or it is impossible at all? Igor is busy right now, so he asked you to help Oleg. Can you answer this question?

Input

The first line contains two integers n and k (1 ≤ n ≤ 105, 1 ≤ k ≤ 109) — the number of share prices, and the amount of rubles some price decreases each second.

The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109) — the initial prices.

Output

Print the only line containing the minimum number of seconds needed for prices to become equal, of «-1» if it is impossible.

Examples
input
3 3
12 9 15
output
3
input
2 2
10 9
output
-1
input
4 1
1 1000000000 1000000000 1000000000
output
2999999997
Note

Consider the first example.

Suppose the third price decreases in the first second and become equal 12 rubles, then the first price decreases and becomes equal 9rubles, and in the third second the third price decreases again and becomes equal 9 rubles. In this case all prices become equal 9 rubles in 3 seconds.

There could be other possibilities, but this minimizes the time needed for all prices to become equal. Thus the answer is 3.

In the second example we can notice that parity of first and second price is different and never changes within described process. Thus prices never can become equal.

In the third example following scenario can take place: firstly, the second price drops, then the third price, and then fourth price. It happens 999999999 times, and, since in one second only one price can drop, the whole process takes999999999 * 3 = 2999999997 seconds. We can note that this is the minimum possible time.

题意:

一个叫Oleg的人每天都要看股,发现n个股价每一秒钟都有且仅有1个股价要跌k卢布

问如果让他们都跌到一样至少需要多少时间,如果没法就输出-1

解:假设某只股票现在是a元,要以k为步调跌到m元的话,需要存在x>0使得 m = a - kx,换一下就是a和m模k同余(用空时记己总结一下数论好了)


import java.util.Scanner;

/**
 * 作者:张宇翔 创建日期:2017年4月23日 下午3:58:22 描述:
 */

public class test {

	private static final int Max=(int) (1e5+10);
	private static int n;
	private static int k;
	private static int A[];
	private static int Min;
	public static void main(String[] args) {
		Init();
		long ans=0;
		boolean ok=true;
		for(int i=0;i<n;i++){
			if((A[i]-Min)%k==0){
				ans+=((A[i]-Min)/k);
			}else{
				ok=false;
				break;
			}
		}
//		System.out.println(Min);
		if(!ok){
			System.out.println(-1);
		}else{
			System.out.println(ans);
		}
	}
	private static void Init(){
		Scanner cin=new Scanner(System.in);
		n=cin.nextInt();
		k=cin.nextInt();
		A=new int[Max];
		Min=(int) (1e9+10);
		for(int i=0;i<n;i++){
			A[i]=cin.nextInt();
			Min=Math.min(Min, A[i]);
		}
	}
	
	
	

}

B. Igor and his way to work
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Woken up by the alarm clock Igor the financial analyst hurried up to the work. He ate his breakfast and sat in his car. Sadly, when he opened his GPS navigator, he found that some of the roads in Bankopolis, the city where he lives, are closed due to road works. Moreover, Igor has some problems with the steering wheel, so he can make no more than two turns on his way to his office in bank.

Bankopolis looks like a grid of n rows and m columns. Igor should find a way from his home to the bank that has no more than two turns and doesn't contain cells with road works, or determine that it is impossible and he should work from home. A turn is a change in movement direction. Igor's car can only move to the left, to the right, upwards and downwards. Initially Igor can choose any direction. Igor is still sleepy, so you should help him.

Input

The first line contains two integers n and m (1 ≤ n, m ≤ 1000) — the number of rows and the number of columns in the grid.

Each of the next n lines contains m characters denoting the corresponding row of the grid. The following characters can occur:

  • "." — an empty cell;
  • "*" — a cell with road works;
  • "S" — the cell where Igor's home is located;
  • "T" — the cell where Igor's office is located.

It is guaranteed that "S" and "T" appear exactly once each.

Output

In the only line print "YES" if there is a path between Igor's home and Igor's office with no more than two turns, and "NO" otherwise.

Examples
input
5 5
..S..
****.
T....
****.
.....
output
YES
input
5 5
S....
****.
.....
.****
..T..
output
NO
Note

The first sample is shown on the following picture:

In the second sample it is impossible to reach Igor's office using less that 4 turns, thus there exists no path using no more than 2 turns. The path using exactly 4 turns is shown on this picture:


题意:告诉你起点和终点,要求你在只能转弯两次的情况下能不能到达终点。能就输出“YES”,不能就输出“NO”。

解:这算是经典的转弯题了。这个题关键就是“判重”,如何记录走过的点。我们可以开个三维数组,记录各个坐标各个方向上的转弯数,如果下次在到这个点这个方向,那就比较转弯数,如果这次转弯数大于等于已经记录的转弯数那就不用再找下去了,因为这次能走到的地方,上次肯定也能走到。估计一下时间复杂度大概为O(2n)。太久没写搜索了,技术不如从前了............................

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

/**
 * 作者:张宇翔 创建日期:2017年4月23日 下午3:58:22 描述:
 */

public class test {

	private static final int Max = (int) (1e3 + 10);
	private static int n;
	private static int m;
	private static String[] s;
	private static int[][] dir = new int[][] { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
	private static int startx, starty, endx, endy;
	private static int vis[][][];
	private static boolean ok;

	public static void main(String[] args) throws Exception {
		Init();
		BFS();
		if (!ok) {
			System.out.println("NO");
		}
	}

	private static void Init() throws Exception {
		SC cin = new SC(System.in);
		n = cin.nextInt();
		m = cin.nextInt();
		vis = new int[Max][Max][10];
		s = new String[Max];
		ok = false;
		for (int i = 0; i < n; i++) {
			s[i] = cin.next();
			for (int j = 0; j < m; j++) {
				if (s[i].charAt(j) == 'S') {
					startx = i;
					starty = j;
				}
				if (s[i].charAt(j) == 'T') {
					endx = i;
					endy = j;
				}
			}
		}
		for(int i=0;i<Max;i++){
			for(int j=0;j<Max;j++){
				for(int k=0;k<4;k++){
					vis[i][j][k]=Integer.MAX_VALUE;
				}
			}
		}
		// System.out.println(startx+" "+starty);
		// System.out.println(endx+" "+endy);
	}

	private static void BFS() {
		Queue<Node> queue = new LinkedList<Node>();
		Node node = new Node(startx, starty, 0, 0, 0);
		queue.add(node);
		while (!queue.isEmpty()) {
			Node pre = queue.poll();
			if (pre.getX() == endx && pre.getY() == endy) {
				ok = true;
//				System.out.println("转弯:" + pre.getTurn());
//				System.out.println("步数:" + pre.step);
				System.out.println("YES");
				return;
			}
			for (int i = 0; i < 4; i++) {
				Node node2 = new Node();
				node2.setX(pre.getX() + dir[i][0]);
				node2.setY(pre.getY() + dir[i][1]);
				node2.setStep(pre.getStep() + 1);
				if (node2.getX() - pre.getX() == 1) {
					node2.setDirection(2);
					if (pre.getDirection() != 2 && pre.getDirection() != 0 && pre.getDirection() != 1) {
						node2.setTurn(pre.getTurn() + 1);
					} else {
						node2.setTurn(pre.getTurn());
					}
				} else if (node2.getX() - pre.getX() == -1) {
					node2.setDirection(1);
					if (pre.getDirection() != 1 && pre.getDirection() != 0 && pre.getDirection() != 2) {
						node2.setTurn(pre.getTurn() + 1);
					} else {
						node2.setTurn(pre.getTurn());
					}
				} else if (node2.getY() - pre.getY() == 1) {
					node2.setDirection(4);
					if (pre.getDirection() != 4 && pre.getDirection() != 0 && pre.getDirection() != 3) {
						node2.setTurn(pre.getTurn() + 1);
					} else {
						node2.setTurn(pre.getTurn());
					}
				} else if (node2.getY() - pre.getY() == -1) {
					node2.setDirection(3);
					if (pre.getDirection() != 3 && pre.getDirection() != 0 && pre.getDirection() != 4) {
						node2.setTurn(pre.getTurn() + 1);
					} else {
						node2.setTurn(pre.getTurn());
					}
				}
				if (check(node2.getX(), node2.getY(), node2.getTurn())) {
					if(vis[node2.getX()][node2.getY()][i]>node2.getTurn()){
						vis[node2.getX()][node2.getY()][i] = node2.getTurn();
						queue.add(node2);
					}
				}
			}
		}
	}


	// 合法返回true,不合法返回false
	private static boolean check(int x, int y, int turn) {
		if (x >= 0 && x < n && y >= 0 && y < m && (turn <= 2) && (s[x].charAt(y) != '*'))
			return true;
		return false;
	}

	static class Node {
		int x;// x轴坐标
		int y;// y轴坐标
		int step;// 步数
		int turn;// 转弯的数量
		int direction;// 方向 0:表示起始方向,1表示向左,2表示向右,3表示向上,4表示向下

		public int getX() {
			return x;
		}

		public void setX(int x) {
			this.x = x;
		}

		public int getY() {
			return y;
		}

		public void setY(int y) {
			this.y = y;
		}

		public int getStep() {
			return step;
		}

		public void setStep(int step) {
			this.step = step;
		}

		public int getTurn() {
			return turn;
		}

		public void setTurn(int turn) {
			this.turn = turn;
		}

		public int getDirection() {
			return direction;
		}

		public void setDirection(int direction) {
			this.direction = direction;
		}

		public Node(int x, int y, int step, int turn, int direction) {
			super();
			this.x = x;
			this.y = y;
			this.step = step;
			this.turn = turn;
			this.direction = direction;
		}

		public Node() {
			super();
		}

	}

	static class SC {
		BufferedReader br;
		StringTokenizer st;

		SC(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		int nextInt() throws NumberFormatException, IOException {
			return Integer.parseInt(next());
		}

		long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}
	}
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值