倪文迪陪你学藍橋杯2021冬休み毎日一題:1.16日(2018省試合A組第4題)
37441 ワード
2021年冬休み毎日1題、2017~2019年の省試合本題.本文の内容は倪文迪(華東理工大学コンピュータ学部ソフトウェア192クラス)と羅勇軍先生から提供された.次の毎日の問題は、新しいブログを出します.毎日ブルーブリッジカップのコラムを見てください.https://blog.csdn.net/weixin_43914593/category_10721247.html
各問題にはC++、Java、Pythonの3言語のコードが提供されている.Pythonは強力で威厳があり、符号化が簡潔であるため、後のブログは主にPythonコードで解釈され、もちろんC++とJavaのコードが添付されている.
文書ディレクトリ1、題名説明 2、説明 3、Pythonコード 3.1暴力捜査 3.2硬算+並べ替え 3.3優先キュー+setデポジット 4、C++コード 4.1暴力捜査 4.2優先キュー+mpデウェイト 4.3 set+upper_bound
5、Javaコード 5.1暴力捜査 5.6優先キュー+setデポジット
2018省試合A組第4題、タイトルリンク:いくつ目のラッキー数http://oj.ecustacm.cn/problem.php?id=1362
1、テーマの説明
x星を旅行する観光客は、観光客番号として整数で送られます.x星の王は変な癖があって、彼は数字3,5と7しか好きではありません.王は、観光客の番号に因子:3,5,7だけが含まれていれば、賞品をもらうことができると規定しています.上位10のラッキーナンバーは:3 5 7 9 15 21 25 27 35 45で、11番目のラッキーナンバーは:49小明がラッキーナンバー5908470958505を受け取った.賞をもらうとき、これが何番目のラッキーな数字だと正確に言ってください.そうしないと、賞品がもらえません.明ちゃんの計算を手伝ってください.59084709587505はいくつかのラッキーな数字です.
2、説明
ゞ 填空,送分?ゞ 59084709587505という数はそれほど大きくなく,C++のunsigned long型で,最大値は2 64−1=18446744073709551615^{64}−1=18446744073709551615 264−1=18446744073709551615であった.
3、Pythonコード
3.1暴力捜査
このシリーズの数は3 iと表すことができる× 5 j × 7 k 3^i\times5^j\times7^k 3i×5j×7 k、範囲を超えないすべてのi、j、k i、j、k i、j、kの組み合わせを検索すればよい. Pythonは大数の心配はありませんので、ループのついでに大きな範囲を取って終了条件にすればいいのですが、次のコードの3 50 3^{50}350は59084709587505を超えるに違いありません.
3.2ハード計算+ソート
Python符号化は極めて容易であるため、すべての3、5、7の倍数を無理に算出してから、59084709587505の位置を並べ替えて見つけても、符号化は容易である.
3.3優先キュー+setデリバリー
上の「3.2硬算+ソート」の考え方は、優先キューで実現できる.新しい数が生成されるたびに優先キューに入れる.キューからポップアップされるたびに最小であり、ソートを実現することに相当する.またキューに入れるときはsetで重み付けする.
4、C++コード
以下にC++のいくつかの実装を示し,説明するのがおっくうである.
4.1暴力捜査
4.2優先キュー+mpデポジット
4.3 set+upper_bound
5、Javaコード
5.1暴力捜査
5.6優先キュー+setデリバリー
各問題にはC++、Java、Pythonの3言語のコードが提供されている.Pythonは強力で威厳があり、符号化が簡潔であるため、後のブログは主にPythonコードで解釈され、もちろんC++とJavaのコードが添付されている.
文書ディレクトリ
2018省試合A組第4題、タイトルリンク:いくつ目のラッキー数http://oj.ecustacm.cn/problem.php?id=1362
1、テーマの説明
x星を旅行する観光客は、観光客番号として整数で送られます.x星の王は変な癖があって、彼は数字3,5と7しか好きではありません.王は、観光客の番号に因子:3,5,7だけが含まれていれば、賞品をもらうことができると規定しています.上位10のラッキーナンバーは:3 5 7 9 15 21 25 27 35 45で、11番目のラッキーナンバーは:49小明がラッキーナンバー5908470958505を受け取った.賞をもらうとき、これが何番目のラッキーな数字だと正確に言ってください.そうしないと、賞品がもらえません.明ちゃんの計算を手伝ってください.59084709587505はいくつかのラッキーな数字です.
2、説明
ゞ 填空,送分?ゞ 59084709587505という数はそれほど大きくなく,C++のunsigned long型で,最大値は2 64−1=18446744073709551615^{64}−1=18446744073709551615 264−1=18446744073709551615であった.
3、Pythonコード
3.1暴力捜査
このシリーズの数は3 iと表すことができる× 5 j × 7 k 3^i\times5^j\times7^k 3i×5j×7 k、範囲を超えないすべてのi、j、k i、j、k i、j、kの組み合わせを検索すればよい. Pythonは大数の心配はありませんので、ループのついでに大きな範囲を取って終了条件にすればいいのですが、次のコードの3 50 3^{50}350は59084709587505を超えるに違いありません.
cnt = 0
for i in range(50):
for j in range(50):
for k in range(50):
r1 = 3**i
r2 = 5**j
r3 = 7**k
if r1*r2*r3 < 59084709587505: # <=
cnt += 1
print(cnt )
3.2ハード計算+ソート
Python符号化は極めて容易であるため、すべての3、5、7の倍数を無理に算出してから、59084709587505の位置を並べ替えて見つけても、符号化は容易である.
n = 59084709587505
a = [1] # 3、5、7
k = 0
while True:
for i in range(3, 8, 2): # 3、5、7
tmp = i*a[k] #
if tmp not in a: #
a.append(tmp) #
a.sort() #
if tmp > 2**64: #
print(a.index(n)) #
exit(0)
k += 1
3.3優先キュー+setデリバリー
上の「3.2硬算+ソート」の考え方は、優先キューで実現できる.新しい数が生成されるたびに優先キューに入れる.キューからポップアップされるたびに最小であり、ソートを実現することに相当する.またキューに入れるときはsetで重み付けする.
import queue
q = queue.PriorityQueue() # ,
s = set() #
q.put(1)
s.add(1)
cnt = 0
while True:
n = q.get()
if n == 59084709587505:
break
cnt += 1
for i in range(3, 8, 2): #3、5、7
t = n * i #
if t not in s: #
q.put(t)
s.add(t)
print(cnt)
4、C++コード
以下にC++のいくつかの実装を示し,説明するのがおっくうである.
4.1暴力捜査
#include
using namespace std;
int main(void){
long long n = 59084709587505;
int cnt = 0;
for(int i=0;pow(3,i)<n;i++) // <=
for(int j=0;pow(5,j)<n;j++)
for(int k=0;pow(7,k)<n;k++)
if(pow(3,i)*pow(5,j)*pow(7,k)<n)
cnt++;
cout<<cnt;
return 0;
}
4.2優先キュー+mpデポジット
//new oj User: 190101041
#include
#define ll long long
using namespace std;
typedef priority_queue<ll,vector<ll>,greater<ll> > pq;
typedef map<ll,int> mp;
mp vis;
int sum[5]={
3,5,7};
int main(){
ll tem=59084709587505;
pq qu;
qu.push(1);
int ans=0;
while(1){
ll cnt=qu.top();
qu.pop();
if(cnt==tem){
cout<<ans<<endl;
break;
}
ll temcnt;
for(int i=0;i<3;i++){
temcnt=cnt*sum[i];
if(vis[temcnt]==0){
qu.push(temcnt);
vis[temcnt]=1;
}
}
ans++;
}
}
4.3 set+upper_bound
//new oj User: 311706000426
#include
using namespace std;
typedef long long LL;
set<LL> se;
int main(){
LL f = 1;
LL a[3] = {
3,5,7};
while(1){
for(int i=0;i<3;i++)
if(f*a[i]<=59084709587505)
se.insert(f*a[i]);
f = *se.upper_bound(f);
if(f>=59084709587505)
break;
}
cout<<se.size();
return 0;
}
5、Javaコード
5.1暴力捜査
public class Main{
public static void main(String[] args) {
int count=0;
long n=59084709587505L;
for(int i=0;Math.pow(3,i)<n;i++){
for(int j=0;Math.pow(5,j)<n;j++){
for(int k=0;Math.pow(7,k)<n;k++){
if(Math.pow(3,i)*Math.pow(5,j)*Math.pow(7,k)<n){
count++;
}
}
}
}
System.out.println(count);
}
}
5.6優先キュー+setデリバリー
//new oj User: coder370
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in) ;
long n = 59084709587505L ;
int x=0,y=0,z=0 ;
long t=n ;
while(t%3==0) {
t/=3;++x;}
while(t%5==0) {
t/=5;++y;}
while(t%7==0) {
t/=7;++z;}
int mx=Math.max(x,y) ;
mx = Math.max(mx, z) ;
PriorityQueue<Long> q = new PriorityQueue<Long>() ;
Set<Long> st = new HashSet<Long>() ;
long[] num = {
3,5,7} ;
for(int i=0 ; i<3 ; ++i) {
q.add(num[i]) ; st.add(num[i]);}
int cnt=0 ;
while(q.isEmpty()==false) {
long h = q.poll() ;
++cnt ;
if(h==n) break ;
for(int i=0 ; i<3 ; ++i) {
t = h*num[i] ;
if(t>n) continue ;
if(st.contains(t)==false) {
q.add(t) ;
st.add(t) ;
}
}
}
System.out.println(cnt);
}
}