λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
μ•Œκ³ λ¦¬μ¦˜ πŸ‘©πŸ»‍πŸ’»/λ°±μ€€

#9421

by flowing1ife 2023. 3. 17.
  • 문제

μ–‘μ˜ μ •μˆ˜ n의 각 자리수의 제곱의 합을 κ³„μ‚°ν•œλ‹€. κ·Έλ ‡κ²Œ ν•΄μ„œ λ‚˜μ˜¨ 합도 각 자리수의 제곱의 합을 κ³„μ‚°ν•œλ‹€. μ΄λ ‡κ²Œ λ°˜λ³΅ν•΄μ„œ 1이 λ‚˜μ˜¨λ‹€λ©΄, n을 μƒκ·Όμˆ˜λΌκ³  ν•œλ‹€.

700은 μƒκ·Όμˆ˜μ΄λ‹€.

  • 72 + 02 + 02 = 49
  • 42 + 92 = 97
  • 92 + 72 = 130
  • 12 + 32 + 02 = 10
  • 12 + 02 = 1

2λŠ” μƒκ·Όμˆ˜κ°€ μ•„λ‹ˆλ‹€.

  • 22 = 4
  • 42 = 16
  • 12 + 62 = 37
  • 32 + 72 = 58
  • 52 + 82 = 89
  • 82 + 92 = 145
  • 12 + 42 + 52 = 42
  • 42 + 22 = 20
  • 22 + 02 = 4
  • 42 = 16
  • ... λλ‚˜μ§€ μ•ŠλŠ”λ‹€

μ†Œμˆ˜λŠ” 1κ³Ό μžκΈ°μžμ‹ μ„ μ œμ™Έν•˜κ³  μ•½μˆ˜κ°€ μ—†λŠ” μˆ˜μ΄λ‹€. 2, 3, 5, 7, 11, 13, 17, 19, ... λŠ” μ†Œμˆ˜μ΄λ‹€.

μ†Œμˆ˜μƒκ·Όμˆ˜λŠ” μ†Œμˆ˜μ΄λ©΄μ„œ μƒκ·Όμˆ˜μΈ μˆ«μžμ΄λ‹€. 7, 13, 19, ... λŠ” μ†Œμˆ˜ μƒκ·Όμˆ˜μ΄λ‹€.

n이 μ£Όμ–΄μ‘Œμ„ λ•Œ, n보닀 μž‘κ±°λ‚˜ 같은 λͺ¨λ“  μ†Œμˆ˜μƒκ·Όμˆ˜λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

  • μ½”λ“œ
#include <iostream>
#include <vector>
#include <set>

using namespace std;

void isPrime(int n, vector<bool>& is_prime){
	is_prime[0] = is_prime[1] = false;

	for (int i = 2; i * i <= n; i++) {
		if (is_prime[i]) {
			for (int j = i * i; j <= n; j += i) {
				is_prime[j] = false;
			}
		}
	}
}

void isSanggeun(int n, vector<bool>& is_prime) {
	is_prime[2] = is_prime[3] = is_prime[5] = false; // 초반 μƒκ·Όμˆ˜κ°€ μ•„λ‹Œ 것듀 μ§€μš°κΈ°

	for (int i = 7; i <= n; i++) {
		if (is_prime[i]) { //μ†Œμˆ˜μ΄λ©΄ μƒκ·Όμˆ˜μΈμ§€ 확인
			set <int> s; //μƒκ·Όμˆ˜ 계산결과λ₯Ό μ €μž₯ν•  set
			int num = i; //계산할 κ°’
			while (true) {
				int sum = 0; //계산 κ²°κ³Ό
				while (true) { // ν•œ μžλ¦Ώμˆ˜μ”© κ³„μ‚°ν•΄μ„œ λ”ν•˜κΈ° 
					sum += ((num % 10) * (num % 10));
					if (num >= 10) {
						num /= 10;
					}
					else {
						break;
					}
				}
				if (s.find(sum) != s.end()) { // 이미 ν•œ 번 κ³„μ‚°ν•œ 결과라면 
					is_prime[i] = false;
					break;
				}
				else if (sum == 1) {
					break;
				}
				else {
					s.insert(sum);
					num = sum; //num κ°±μ‹ 
				}
			}

		}
	}
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	int n;
	vector<bool>is_prime;

	//μž…λ ₯
	cin >> n;

	//μ—°μ‚°
	//미리 nκΉŒμ§€μ˜ μ†Œμˆ˜ κ΅¬ν•˜κΈ°
	is_prime.assign(n + 1, true);
	isPrime(n, is_prime);
	//nκΉŒμ§€μ˜ μ†Œμˆ˜ μƒκ·Όμˆ˜ κ΅¬ν•˜κΈ°
	isSanggeun(n, is_prime);

	//좜λ ₯
	for (int i = 7; i <= n; i++) {
		if (is_prime[i]) {
			cout << i << "\n";
		}
	}
	

}
  • ν•΄μ„€

1. isPrime ν•¨μˆ˜

- μ—λΌν† μŠ€ν…Œλ„€μŠ€μ˜ 체λ₯Ό μ΄μš©ν•˜μ—¬ nκΉŒμ§€μ˜ μ†Œμˆ˜λ₯Ό κ΅¬ν•˜λŠ” ν•¨μˆ˜

 

2. isSanggeun ν•¨μˆ˜

- μ†Œμˆ˜μƒκ·Όμˆ˜λ₯Ό κ΅¬ν•˜λŠ” ν•¨μˆ˜

- 연산을 λ°˜λ³΅ν•˜λ‹€κ°€ 같은 κ²°κ³Όκ°€ λ‚˜μ˜€λ©΄ κ·Έλ•ŒλΆ€ν„°λŠ” μ†Œμˆ˜μƒκ·Όμˆ˜μ— ν•΄λ‹Ήν•˜μ§€ μ•ŠμŒ

: λ¨Όμ € 초반 μƒκ·Όμˆ˜κ°€ μ•„λ‹Œ 것듀 false둜 μ§€μš°κΈ°

: 7λΆ€ν„° nκΉŒμ§€ μ†Œμˆ˜μ΄λ©΄ μƒκ·Όμˆ˜μΈμ§€ 확인

: sum에 첫째 μžλ¦¬λΆ€ν„° μ œκ³±ν•΄μ„œ μ €μž₯

: num이 10보닀 ν¬κ±°λ‚˜ κ°™μœΌλ©΄ 10으둜 λ‚˜λˆˆ λ’€ 반볡, λ§Œμ•½ 이제 10보닀 μž‘μœΌλ©΄ ν•œ μžλ¦¬μ”© 계산을 μ™„λ£Œν•œ κ²ƒμ΄λ―€λ‘œ break

: 이후 set에 이미 sum이 μ‘΄μž¬ν•˜λ©΄ μ†Œμˆ˜ μƒκ·Όμˆ˜κ°€ μ•„λ‹ˆλ―€λ‘œ iλ₯Ό false둜 μ§€μš΄ λ’€ break

: λ§Œμ•½ sum이 1이라면 μ†Œμˆ˜ μƒκ·Όμˆ˜μ΄λ―€λ‘œ κ·Έλƒ₯ break

: λ§Œμ•½ μœ„ 두가지 λͺ¨λ‘μ— ν•΄λ‹Ήν•˜μ§€ μ•ŠλŠ”λ‹€λ©΄ 계속 κ³„μ‚°ν•΄μ•Όν•˜λ―€λ‘œ sum을 s에 λ„£κ³  num에 sum을 λŒ€μž…ν•΄ λ‹€μ‹œ μ—°μ‚° 반볡

 

3. main ν•¨μˆ˜

: isPrime ν•¨μˆ˜λ₯Ό 톡해 nκΉŒμ§€ μ†Œμˆ˜ λͺ¨λ‘ κ΅¬ν•˜κΈ°

: isSanggeum ν•¨μˆ˜λ₯Ό 톡해 nκΉŒμ§€ μ†Œμˆ˜ μƒκ·Όμˆ˜ λͺ¨λ‘ κ΅¬ν•˜κΈ°

'μ•Œκ³ λ¦¬μ¦˜ πŸ‘©πŸ»β€πŸ’» > λ°±μ€€' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

#1436  (0) 2023.03.21
#1065  (0) 2023.03.21
#2981  (0) 2023.03.17
#6588  (1) 2023.03.17
#2840  (0) 2023.03.17