[伯俊C++]1193噴水を探して


質問する


無限大の配列には以下の点数が書かれています.
のようにリストされている点数は、1/1→1/2→2/1→3/1→2/2→…の順に1番、2番、3番、4番、5番、…の順になります.
Xが与えられた場合、Xの2番目の点数を求めるプログラムを作成してください.

入力


第1行は、X(1≦X≦1000000)を与える.

しゅつりょく


1行目にスコアを出力します.
https://www.acmicpc.net/problem/1193

に答える


個人的には、ブロンズ問題であれば、初めて見るとどのように近づくか、考えるべき問題です.
一般座標系で移動点を位置決めするときは、常に
方向ベクトルdxdyを宣言することを推奨します.これを体現すれば、問題は容易になる.

上の図に示すように、問題では1-2-3-4-1-2-""の順に移動し、それぞれの場合の方向ベクトルを下図に示すことができます.

dirはdx,dyに用いる方向順序である.bool check変数を用いたが,右側(3)の下側(1)のため,同時に1回だけ移動して再び転向した.

ブロンズ問題としてはかなり価値のある問題だと思います.
#define _CRT_SECURE_NO_WARNINGS 
#include <bits/stdc++.h>
int X;
int dx[4] = {1, 1, -1, 0}; //좌하, 하, 우상, 우 순서로반복
int dy[4] = {-1, 0, 1, 1};

int main() {
	scanf("%d", &X);
	if (X == 1) { //예외처리해버렷음
		printf("1/1");
		return 0;
	}
	int dir = 0;
	int x = 1, y = 2; //초기값 1/2
	bool check = false;
	for (int i = 2; i < X; i++) {
		int xx = x + dx[dir];
		int yy = y + dy[dir];
		if (dir == 1 || dir == 3) check = true;
		x = xx; y = yy; //분수 갱신

		//방향을 바꾸는경우를 체크
		if ((dir == 0 && yy == 1) || (dir == 1 && check) ||
			(dir == 2 && xx == 1) || (dir == 3 && check)) {
			check = false;
			dir++;
		}
		if (dir == 4) dir = 0; //방향 순환
		//printf(">> %d %d\n", x, y);
	}
	printf("%d/%d", x, y);

	return 0;
}