2020ブルーブリッジカップ州大会グループBC ++(ゲーム1)実際の質問

1.ランニングトレーニング(5点)

XiaoMingはランニングトレーニングを行う予定です。

当初、シャオミンは体力に溢れており、体力は1万人と計算されています。シャオミンが走った場合、彼は毎分負けます

600スタミナ。シャオミンが休むと、彼は毎分300体力を上げます。体力の喪失と増加は両方とも

均等に変化します。

Xiao Mingは、1分間走り、1分間休憩し、さらに1分間走り、さらに1分間休憩する予定です...など。

リング。シャオミンの体力がゼロに達すると、運動をやめます。

Xiao Mingはどのくらい運動をやめますか?答えを整数にするには、秒単位で答えを出力してください。

回答の単位ではなく、番号のみを入力してください。

回答:3880

2.記念日(5点)

2020年7月1日は中国共産党創立99周年です。

中国共産党は1921年7月23日に設立されました。

1921年7月23日正午12時から2020年7月1日正午までのトータルパッケージをお願いします。

何分含まれていますか?

回答:52,038,720

3.複合テスト(10点)

新しいクラウンの流行は、新しいクラウンウイルスによって引き起こされ、最近A国で蔓延しています。

ウイルス核酸検査のために多数の人々を準備します。ただし、テスト用のキットは不足しています。

この困難を解決するために、科学者たちは方法を考えました:複合テスト。複数の人から来る(k

A)採取した検体は、同じキットに入れて検査します。結果が負の場合、これはこのkを意味します

すべての個人が陰性であり、k人の個人が1つのキットでテストされています結果が正の場合、それは

少なくとも1人が陽性でありこれらのk人のすべてのサンプルを個別に再度テストする必要があります(理論的には、

テスト前にkk1人が陰性の場合k番目の人が陽性であると推測できますが、実際の操作では

この推論は使用されませんが、k人の個人個別テストされます)、および最初の複合テスト、合計

a k +完了。1つの試薬カートリッジkの個別検出器。

国Aは、検査を受けた人々の感染率は約1%であり、均等に分布していると推定しています。kどれくらいかかることができますか

最も経済的なキット?

国Aにn人の個人がいて、n / 100人の感染者がいると仮定します。

k人の各グループ、合計n / kグループ、n / kボトルの試薬を共有します。最悪の場合、kボトルの試薬が追加の感染者ごとに使用されるため、n / k +(n / 100)* k本の試薬が共有されます

nは固定値なので、(1 / k + k / 100)の最小値を見つけます

a = bの場合に限り、a + b> =2√abなので、1 / k = k / 100の等号を取り、最小値を取得します。

k = 10を解きます

4. REPEATプログラム(10ポイント)

添付のprog.txtは特定の言語で書かれたプログラムです。

これらの中でも、リピートkが表すのサイクルkはループ制御の範囲はインデントで表されます。

次の行から、その行よりも大きい連続インデント(前の空白が長い)がループに含まれるコンテンツです。

たとえば、次のスニペット:

REPEAT 2:
	A = A + 4
	REPEAT 5:
		REPEAT 6:
			A = A + 5
		A = A + 7
	A = A + 8
A = A + 9

フラグメントでは、A = A +4の行からA = A +8の行までが最初の行にあります

ループ内で2回。

REPEAT 6:A = A +7の行はREPEAT5:ループ内にあります。

A = A +5実際の合計サイクル数は2×5×6 = 60回です。

プログラムが実行された後、Aの値は何ですか?

アイデア:ループの情報を格納するスタックを構築できます。変数timesは、現在の行数が実行された回数を格納します。テキストを観察したところ、現在の行番号の「レベル」は、各行の前のスペースの数で判断でき、4つのスペースがレベル​​を表していることがわかりました。現在の行レベルが前のループのレベルよりも低い場合は、前のループを終了したことを意味し、スタックと時間を変更できます。次に、テキスト全体ですべての数値が単位番号であることがわかりました。そのため、ループを使用して数値を直接検索し、行の有意な数を抽出できます。

回答: 241830

#include<bits/stdc++.h>
using namespace std;

int main()
{
	string string_;
	stack<long long> stack_; 
	freopen("prog.txt", "rb", stdin);
	getline(cin, string_);//读第一行 A=0 
	long long A=0,times=1,old_counts=0;//A=0,当前倍数,老的层数 
	while(getline(cin, string_))
	{
		long long counts=0;//当前的层数,
		for(counts=0; counts < string_.size(); counts++)
		{
			//记录空格数 4个空格是一层 
			if(string_[counts] != ' ')
				break;
		}
		counts /= 4;//这句话的层数 
		while(counts < old_counts)//新层数低 则退出一层循环 pop 
		{
			times /= stack_.top();
			stack_.pop();
			old_counts--; 
		} 
		if(string_[counts*4] == 'R')//R开头就是新增循环
		{
			for(long long now=counts*4; now < string_.size(); now++)//找到数字 
			{
				if(string_[now]>='0' && string_[now]<='9')//如果是数字 
				{
					stack_.push(string_[now]-'0');
					times *= string_[now]-'0';
					old_counts++;
					break; 
				} 
			}
		} else{
			for(long long now = counts*4;now < string_.size(); now++)//找到数字 
			{
				if(string_[now] >= '0' && string_[now] <= '9')//如果是数字 
				{
					A += (string_[now]-'0') *times;
					break; 
				} 
			}
		} 
	}
	cout<<A; 
	return 0;
} 

5.マトリックス(15ポイント)

1〜2020を2×1010の行列に入れます。同じ行の右側が左側よりも大きく、同じ列の下側が上側よりも大きい必要があります。オプションはいくつありますか?

答えは大きいです、あなたは2020年で割った計画の数の残りを与える必要があるだけです。

回答:1340

#include<bits/stdc++.h>
using namespace std;

int f[1020][1020];

int main()
{
    f[0][0] = 1;                                   // 两行一个数字都不放,也是一种方案
    for (int i = 0; i <= 1010; i ++)
        for (int j = 0; j <= 1010; j ++)
        {
            if(i - 1 >= j)                         // 转移前的状态也要合法,即第一行的数量不小于第二行的数量
            	f[i][j] += f[i - 1][j] % 2020;
            if(j)
            	f[i][j] += f[i][j - 1] % 2020;
        }
        
    cout << f[1010][1010] << endl;   
    return 0;
}

6.分割シーケンス(15ポイント)

問題の説明

シーケンスがあり、シーケンスの最初の番号はnで、その後の各番号は2で割り切れる前の番号です。入力してください

この順序で正の値を持つアイテムを取得します。

入力フォーマット

入力行には整数nが含まれています

出力フォーマット

複数の整数を含み、隣接する整数間のスペースで区切られた1行を出力し、答えを示します。

サンプル入力

20

サンプル出力

20 10 5 2 1

テストデータ

評価のユースケースの80%を、1≤ N ≤^ 9 10

すべての評価のユースケースのために、1≤ N ≤10 ^ 18

#include<bits/stdc++.h>
using namespace std;
int main(){
	long long n;
	cin>>n;
	cout<<n;
	while(n/2){
		cout<<' '<<n/2;
		n /= 2;
	}
	return 0;
}

7.デコード(20ポイント)

問題の説明

Xiao Mingには長い英語の文字列があり、大文字と小文字が含まれる場合があります。

この文字列では、多くの連続した文字が繰り返されます。Xiao Mingは、このアルファベットの文字列を組み合わせる方法を考えました

短くする:文字+出現回数の形式で複数の連続した同一の文字を書きます。

たとえば、5つの連続したas、つまりaaaaaの場合、Xiao Mingはa5(またはa4a、

aa3aなど)。この例の場合:HHHellllloo、XiaoMingはH3el5o2と省略できます。便宜上

Da、Xiao Mingは、9つを超える連続した同一文字を省略形で書き込むことはありません。

次に、省略された文字列を指定します。XiaoMingが元の文字列に復元するのを手伝ってください。

入力フォーマット

入力行には文字列が含まれています。

出力フォーマット

復元された文字列を表す文字列を出力します。

サンプル入力

H3el5o2

サンプル出力

HHHellllloo

テストデータ

すべての評価ケースで、文字列は大文字と小文字の英語の文字と数字で構成され、長さはを超えません

100。

元の文字列の長さが100を超える場合があることに注意してください。

#include<bits/stdc++.h>
using namespace std;
int main(){
	string s;
	getline(cin, s);
	int len = s.length();
	int index = 0;
	while(s[index] >= '0' && s[index] <= '9'){
		cout<<s[index++];		
	}
	for(int i = index; i < len; i++){
		if(s[i] < '0' || s[i] > '9'){
			cout<<s[i];
		} else{
			if(s[i-1] < '0' || s[i-1] > '9'){
				for(int j = (s[i] - '0')-1; j > 0; j--){
					cout<<s[i-1];
				}
			}else{
				cout<<s[i];
			}
		}
	}
	return 0;
}

8.正方形を歩く(20ポイント)

問題の説明

平面上にいくつかの2次元格子があります。

これらの点の番号付けは、1行目からn行目まで、上から下への2次元配列の番号付けに似ています

左から順に、1目からm列目です。各点は行番号と列番号で表すことができます。

今、誰かが最初の行と最初の列に立っていて、n番目の行とm番目のに行かなければなりません右または下にしか行けません

行く。

行番号と列番号が両方とも偶数の場合、このグリッドに入ることができないことに注意してください。

オプションがいくつあるか尋ねます。

入力フォーマット

入力行には、2つの整数nmが含まれています

出力フォーマット

答えを示す整数を出力します。

サンプル入力

3 4

サンプル出力

2

サンプル入力

6 6

サンプル出力

0

テストデータ

すべての評価のユースケースのために、1≤ N ≤30、1≤ M ≤30。

#include<bits/stdc++.h>
using namespace std;
int n, m;
int vis[31][31];
int res = 0;

void dfs(int x, int y){
	if(x == n && y == m){
		res++;
		return;
	}
	int next[4][2] = {
   
   {0, 1}, {1, 0}};
	for(int i = 0; i < 2; i++){
		int tx = x + next[i][0];
		int ty = y + next[i][1];
		
		if(tx <= 0 || tx > n || ty <= 0 || ty > m || (tx%2 == 0 && ty%2 == 0)){
			continue;
		}
		if(!vis[tx][ty]){
			vis[tx][ty] = 1;
			dfs(tx, ty);
			vis[tx][ty] = 0;
		}
	}
}

int main(){
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			vis[i][j] = 0;
		}
	}
    cin>>n>>m;
    if(n%2 == 0 && m%2 == 0){
    	cout<<"0";
    	return 0;
	}
	dfs(1, 1);
	cout<<res;
    return 0;
}

9.整数スプライシング(25ポイント)

問題の説明

長さnの配列A1A 2、···、Anを定義します。AiAjの2つの数字を選択できます

iはjと等しくありません)、次にAiAjを次々に新しい整数に結合します。たとえば、12と345は

12345または34512を綴る。AiとAjを交換する順序は、たとえ次の場合でも、常に2つのスペルと見なされることに注意してください。

Ai = Ajの場合

スペルアウトされた整数がKの倍数であることを満足するスペルの数を計算してください

入力フォーマット

最初の行には、2つの整数nKが含まれています

2行目には、n個の整数A 1、A 2、···、Anが含まれています。

出力フォーマット

整数は答えを表します。

サンプル入力

4 2

1 2 3 4

サンプル出力

6

評価のユースケースの規模と慣習

30評価症例の%、1≤ためのN ≤1000 1≤ K ≤20、1≤あい≤104。

すべての評価のユースケースのために、1≤ N ≤105 、1 K ≤105 、および1 アイ≤109。

#include<bits/stdc++.h>
using namespace std;

int ping(int a, int b){
	int len = 0;
	int temp = b;
	while(temp){
		len++;
		temp /= 10;
	}
	return a*pow(10, len) + b;
}

int main(){
	int n, k;
	cin>>n>>k;
	int s[n];
	for(int i = 0; i < n; i++){
		cin>>s[i];
	}
	int sum = 0;
	for(int i = 0; i < n; i++){
		for(int j = i+1; j < n; j++){
			if(ping(s[i], s[j]) % k == 0){
				sum++;
			}
			if(ping(s[j], s[i]) % k == 0){
				sum++;
			}
		}
	}
	cout<<sum;
    return 0;
}

10.ネットワーク分析(25ポイント)

問題の説明

XiaoMingはネットワーク実験を行っています。

彼は、データを送信、受信、保存するために、ノードと呼ばれるn台のコンピューターをセットアップしました

最初は、すべてのノードが独立しており、接続はありません。

Xiao Mingはネットワークケーブルを介して2つのノードを接続でき、2つのノードは接続後に相互に通信できます。

アップ。2つのノードがネットワークケーブルで接続されている場合、それらは隣接ノードと呼ばれます。

Xiao Mingは、そのときにネットワークをテストすることがあり、特定のノードにメッセージを送信し、メッセージが送信されます

隣接する各ノードに送信されると、これらのノードは、すべてが直接送信されるまで、隣接するノードに転送されます。

または、間接的に隣接するノードが情報を受信しました。すべての送信ノードと受信ノードが情報を保存します。

情報は一度だけ保存されます。

Xiaomingの接続とテストのプロセスを考慮して、各ノードに格納されている情報のサイズを計算してください。

入力フォーマット

入力の最初の行には、ノードの数と操作の数をそれぞれ表す2つの整数nmが含まれています。からのノード

1からnまでの数字。

次のm行では、各行の3つの整数が演算を表します。

操作が1の場合、ABは、ノードのことを意味し、AとノードBがネットワークケーブルで接続されています。a = bの場合

の場合、それは自己ループが接続されていることを意味し、ネットワークに実質的な影響はありません。

操作が2ptの場合、サイズtのメッセージがノードpに送信されることを意味します

出力フォーマット

隣接する整数間のスペースで区切られたn個の整数を含む行を出力し、進行状況を順番に示します

上記の操作の後、ノード1からノードn格納される情報のサイズ。

サンプル入力

4 8

1 1 2

2 1 10

2 3 5

1 4 1

2 2 2

1 1 2

1 2 4

2 2 1

サンプル出力

13 13 5 3

テストデータ

30評価症例の%、1≤ためのN ≤20と1≤ M ≤100。

50評価症例の%、1≤ためのN ≤100と1 M ≤1000

70評価症例の%、1≤ためのN ≤1000年1 M ≤10000。

全ての評価の場合について、1≤ N ≤10000 、1 M ≤100000 、および1 T ≤100。

アイデア:中心的なアイデアは、統合して収集することです。配列は古い値を格納するために使用され、配列はルートノードの重みを格納するために使用され、配列は結合された検索の親配列です。2つの操作を実行する場合、操作値のルートノードが検索セットによって検出され、重み付けされます。1つの操作を実行するときに、2つの数値が1つのセットにある場合、操作は実行されません。2つの数値が同じセットにない場合、すべてのノードがトラバースされ、古い値の配列がルートノードの重みに追加されます。その後、ユニオンが動作します。後で計算が繰り返されないように、重み配列をクリアすることを忘れないでください。

#include<bits/stdc++.h>
using namespace std;

int old_[10001],new_[10001],father[10001],n,m;//存老值 存根节点新值 父节点数组 

int find(int a)
{
	return father[a]==a ? a : father[a]=find(father[a]);//路径压缩
}

void union_(int a,int b)
{
	int temp_a=find(a),temp_b=find(b);
	if(temp_a!=temp_b)
	{
		for(register int now=1;now<=n;now++)
		{
			old_[now]+=new_[find(now)];//旧值数组遍历加上权值
		}
		memset(new_,0,sizeof(new_));//重置权值数组,防止重复计算
		father[temp_a]=temp_b;
	}
}

int main()
{
	int a,b,c;
	memset(new_,0,sizeof(new_));
	for(register int now=1;now<=10000;now++)
	{
		father[now]=now;//father数组初始化 
	} 
	scanf("%d %d",&n,&m);
	while(m--)
	{
		scanf("%d %d %d",&a,&b,&c);
		if(a==1)
		{
			union_(b,c);
		}
		else
		{
			new_[find(b)]+=c;
		}
	} 
	for(register int now=1;now<=n;now++)
	{
		printf("%d ",old_[now]+new_[find(now)]);
	}
	return 0;
}

おすすめ

転載: blog.csdn.net/weixin_44723496/article/details/109046825