0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ABC - 128 - A&B&C

Last updated at Posted at 2019-05-27

AtCoder ABC 128 A&B&C&D

AtCoder - 128

近いうちにE&Fを解きに戻ってくる。

A - Apple Pie

	private void solveA() {

		out.println((nextInt() * 3 + nextInt()) / 2);
	}

B - Guidebook

  • 文字列の[][]で保持して、[][0]で文字順にソートして、[][0]が同じだったら[][1]を数値に変換して降順にソート
	private void solveB() {
		int n = nextInt();
		String[][] s = new String[n][3];

		for (int i = 0; i < n; i++) {
			s[i][0] = next();
			s[i][1] = next();
			s[i][2] = Integer.toString(i + 1);
		}
		Arrays.sort(s,
				(x, y) -> {
					if (x[0].compareTo(y[0]) < 0) {
						return -1;
					} else if (x[0].compareTo(y[0]) > 0) {
						return 1;
					} else {
						return -Integer.compare(Integer.parseInt(x[1]), Integer.parseInt(y[1]));
					}
				});

		for (int i = 0; i < s.length; i++) {
			out.println(s[i][2]);
		}
	}

C - Switches

  • 段々書けるようになってきたbit使った全探索

  • スイッチは1-5、スイッチがONになっていないといけない個数 \ スイッチ番号

電球番号\スイッチ番号 1 2 3 4 5
1 0
2 1
  • 電球番号1は、使えるスイッチは1,2,5で、1,2,5の内偶数個(この例だと2つ)がONになっている必要がある
    • 1,2,5全部がONになっているのはNGで、3,4のON/OFFは関係がない
  • 電球番号2は、使えるスイッチは2,3で、2,3の内奇数個(この例だと1つ)がONになっている必要がある
    • 2,3両方がONになっているのはNGで、1,4,5のON/OFFは関係がない

ということで、$2^{スイッチの数}$だけ選択肢があるということになる

具体的には以下のようなパターン($2^{スイッチの数}$個)を試す
出力例3を例にとると

パターン\スイッチ 1 2 3 4 5
1 スイッチ1をON
電球1も2もOFF
2 スイッチ1,2をON
電球1も2もON
3 スイッチ1,2,3をON
電球1がON。電球2はOFF
xxx スイッチ1,5をON
電球1がON。電球2はOFF
	private void solveC() {
		int n = nextInt();
		int m = nextInt();
		int[] k = new int[m];

		List<List<Integer>> s = new ArrayList<List<Integer>>();
		for (int i = 0; i < k.length; i++) {
			k[i] = nextInt();
			List<Integer> temp = new ArrayList<Integer>();
			for (int j = 0; j < k[i]; j++) {
				temp.add(nextInt());
			}
			s.add(temp);
		}
		int[] p = IntStream.range(0, m).map(i -> nextInt()).toArray();

		long res = 0;
		for (int i = 0; i < 1 << n; i++) {
			boolean isResult = true;
			for (int j = 0; j < m; j++) {
				//電球jのボタンリストを取得
				List<Integer> sList = s.get(j);
				//電球jがONになっていないといけないのは偶数か奇数か
				int compareBase = p[j];
				//電球jを点灯するのに必要なボタンのうち、何個ONになっているのか
				int compare = 0;
				for (Integer buttonNum : sList) {
					/*
					 * 電球jのボタンリストの内、ONになっているボタンを探す
					 * buttonNum - 1 -> ボタン番号(配列に合わせて-1)
					 * (i & (1 << (buttonNum - 1)) -> ボタン番号の位置にフラグが立っているか?
					 */
					if ((i & (1 << (buttonNum - 1))) >= 1) {
						compare++;
					}
				}
				//ボタンがONになっていた個数の偶奇を判定し、電球jの必要条件を満たしているのか判定
				if (compareBase != compare % 2) {
					isResult = false;
					break;
				}
			}
			if (isResult) {
				//このパターンは全部の電球がONになった
				res++;
			}

		}

		out.println(res);
	}

D - equeue

  • 以下の4操作を行う
    • 1:左からとる
    • 2:右からとる
    • 3:手持ちを捨てて左につける
    • 4:手持ちを捨てて右につける
  • 3,4は操作の最後で一気に行えばよい(要らないものを最後に捨てるという発想)ので以下の操作を全たパターン行う
    • 左から、$0-max(n,K)$回とる
    • 右から、$0-min(n,(k-lからとった回))$回とる
    • $(k-lからとった回-rからとった回)$分、手持ちから左または右につける
      • 捨てる操作なので左でも右でもどちらでもよい。捨てた後とることをしないので
      • また、0より小さいものは捨てる価値がある(捨てることによって手持ちの価値が上がる)が、0以上は捨てると手持ちの価値が減るので捨てる必要がない
	private void solveD() {
		int n = nextInt();
		int k = nextInt();
		long[] wk = new long[n];
		for (int i = 0; i < n; i++) {
			wk[i] = nextInt();
		}
		long res = 0;
		//左からとれるだけ取る
		for (int l = 0; l <= k; l++) {
			//右からとれるだけ取る
			for (int r = 0; r <= k; r++) {
				//操作回数がkを超えるならbreak
				if (l + r > k) {
					break;
				}

				//現時点の手持ちの合計
				long now = 0;
				List<Long> s = new ArrayList<Long>();
				int pickCount = 0;
				//左側から取得した分だけ足す
				for (int i = 0; i < Integer.min(l, n); i++) {
					long tmp = wk[i];
					now += tmp;
					s.add(tmp);
					pickCount++;
				}
				/*
				 * 右側から取得した分だけ足す
				 * 右側のmaxをいじっているのは、
				 * 	- 操作回数(K)がNより大きい場合があるため
				 *  - 左側から取っていた場合と、右側からとっていった場合で2回ループしているが
				 *   KがNより大きいと同じものをとってしまう場合がある
				 *   そたのめ、本来のrのmax取得数とlで取得した数を比較している。
				 *   e.g.K>=Nの場合、lのInteger.min(l, n)でnが返ってきている。
				 */
				for (int i = n - 1; i > Integer.max(n - 1 - r, Integer.min(l, n)); i--) {
					long tmp = wk[i];
					now += tmp;
					s.add(tmp);
					pickCount++;
				}
				//余計なものを捨てるために、要らない順に並べる
				Collections.sort(s);

				//余分な取得物を捨てることができる回数
				int d = k - pickCount;
				//この回数以上は捨てられないのでbreak
				for (int i = 0; i < Integer.min(d, s.size()); i++) {
					//
					//取り出した宝石の価値が負の値でないなら捨てる必要がない
					if (s.get(i) > 0) {
						break;
					}

					//負の価値の宝石は捨てる
					now -= s.get(i);
				}
				res = Long.max(res, now);
			}
		}
		out.println(res);
	}
0
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?