ゲーム後の質問-アーサー王の真偽

C.アーサー王の真と偽の
トピックの説明

魔術師マーリンは水晶玉でのモルドレッドの反乱を予見し、モルドレッドの反乱の前にアーサー王を守るための効果的な戦略を採用することに決めました。
具体的な方法は次のとおりです。魔法を使ってアーサー王をN個のコピーにコピーします。もちろん、そのうちの1つだけが当てはまります。彼女は、これがアーサー王を殺害から効果的に保護すると信じていました。
最終的にアーサー王を見つけるために、彼女はすべてのアーサー王に1-Nに従って番号を付け、パスワード番号Xを設定しました。True King Arthurの数は、Nに最も近い数であり、2-Xのどの数でも均等に割り切れません。(つまり、真のアーサー王の数の約数は2-Xではなくなりました)。

入る

スペースで区切られた2つの整数X、N。

出力

真のアーサー王の数。

サンプル入力

3 6

サンプル出力

5

サンプル入力

3 4

サンプル出力

1

サンプル入力

5 50

サンプル出力

49

促す

【データ範囲】データの
30%について、2≤X≤N≤102≤X≤N≤102バツN1 0
データの60%について、2≤X≤N≤10002≤X≤N≤10002バツN1 0 0 0
データの80%について、2≤X≤N≤1052≤X≤N≤10^ 52バツN1 05
100%データの場合、2≤X≤N≤1092≤X≤N≤10^ 92バツN1 09

解決策:分類による議論

ヒント:違法な代表者が答えであってはならず、正当な代表者が答えでなければなりません。
既知:整数nnの場合nnn以下nであり、最も近い素数がnnから離れているnはそれほど遠くないので、直接列挙して素数を判断することができます。
最初のタイプx2≥nx^ 2 \ ge nバツ2n
1.合成数は根号以下の因数を持たなければならないため、nn以下です。nのすべての合成数の最小係数は、区間[2、x] [2、x]内にある必要があります[ 2 x ]、したがって[2、n] 2、n]2 n ]の合成数は違法です。
2.[2、x] [2、x][ 2 x ]の各数は違法です。
要約すると、[x + 1、n] [x + 1、n][ x+1 nの素数]は合法かもしれません。
暴力的な判断がnn以下nおよび最も近い素数(x + 1 x +1以上の場合)バツ+1以上xxより大きいx
素数がある場合は、素数を出力します。
何の素数、出力がない場合は1が11[2、n] [2、n]のため[ 2 n ]の数字はどれも合法ではなく、数字11だけが残っています1
2番目のカテゴリx 2 <nx ^ 2 <nバツ2<n
1.合成数は部首以下の因数を持たなければならないため、x 2 x ^ 2以下です。バツ2すべての最小エンゲージメントファクターの数は、区間[2、x] [2、固有です[ 2 x ]、つまり[2、x 2] [2、x ^ 2][ 2 バツ2 ]の合成数は違法ですが、[x 2 + 1、n] [x ^ 2 + 1、n][ x2+1 n ]の合成数は合法かもしれません。
例: x = 2、n = 99 x = 2、n = 99バツ=2 n=9 9時、99 999 9は合法ですが、合成数です。
2. [x + 1、n] [x + 1、n][ x+1 nの素数]は合法かもしれません。
要約すると、nnからnnnより小さくなり始めますnの数は、この数が素数であるか、[2、x] [2、x]でないかを判断し始めます[ 2 x ]の任意の数の倍数である場合は、この数を出力するだけです(部首よりも小さい因数を直接列挙して、[2、x] [2、x]にあるかどうかを判断します。[ 2 X ]遠藤)

#include<cmath>
#include<queue>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

#define mod 77797
typedef long long ll;
const int N = 2e1 + 10;
const ll INF = 0x3f3f3f3f3f3f3f3f;

bool judge(int n, int x) {
    
    
	if (n == 1) return true;
	if (n >= 2 && n <= x) return false;

	for (int i = 2; i <= n / i; i++) {
    
    
		if (n % i == 0) {
    
    
			if (i <= x) return false;
		}
	}
	return true;
}
bool isPrime(ll n) {
    
    
	if (n == 1) return false;
	for (int i = 2; i <= n / i; i++) {
    
    
		if (n % i == 0) {
    
    
			return false;
		}
	}
	return true;
}

int main() {
    
    

	ll x, n;
	cin >> x >> n;

	if (x * x >= n) {
    
    
		while (n > x) {
    
    
			if (isPrime(n)) {
    
    
				cout << n << endl;
				return 0;
			}
			n--;
		}
		cout << 1 << endl;
		return 0;
	}
	else {
    
    
		while (n) {
    
    
			if (judge(n, x)) {
    
    
				cout << n << endl;
				return 0;
			}
			n--;
		}
	}
	return 0;
}

おすすめ

転載: blog.csdn.net/qq_45739057/article/details/113137930