blog

PAT B

任意の正の整数nについて、偶数なら半分に、奇数なら半分に。Karaszはこの推測を1950年の世界数学者会議で発表し、イェール大学の学生や教授陣がこの一見愚かで素朴な命題を証明しようと必死で動いたとい...

Jun 5, 2020 · 7 min. read
シェア

近い将来、PATのA資格を取得することは考えていないので、まずはBのブラッシュアップから始めましょう!

人を殺す1001の仮説

カラス予想:

任意の正の整数nについて、それが偶数なら半分に、奇数なら半分に。カラスは1950年の世界数学者会議でこの推論を発表しました。伝説によると、その当時、イェール大学の学生と教授陣は、この一見非常に愚かで素朴な命題を証明するために必死の試みで動員され、その結果、学生たちは自分の勉強に関心がなくなり、証拠に集中するようになり、これは陰謀であり、カラスはアメリカ数学界の教育と研究の進歩を遅らせるための意図的な試みであると言う人もいるほどです。科学研究の進歩・・・・・・。

今日のトピックはカラッツ予想の証明ではなく、1000を超えない任意の正の整数nが与えられたとき、単純に数えてn=1になるまでに何ステップかかるか?

入力フォーマット

各テスト入力は1つのテストケースを含み、すなわち正の整数nの値を与えます。

出力フォーマット

nから1までの計算に必要なステップ数を出力します。

入力サンプル

3

出力サンプル

5

コード

#include<stdio.h>
int main()
{
	int n,k=0;
	scanf("%d",&n);
	while(n>1)
	{
		n=(n%2)==0?n/2:(3*n+1)/2;
		k++;
	}
	printf("%d
",k);
	return 0;
}

この番号を入力してください。

正の整数nを読み、その桁の和を計算し、和の各桁を羽生ピンインで書きなさい。

入力フォーマット

すなわち、自然数 n の値が与えられます。ここで、n は 10 の 100 乗未満であることが保証されています。

出力フォーマット

n の各桁の合計を 1 行に出力します。ピンイン桁とピンイン桁の間は 1 文字空けますが、1 行の最後のピンイン桁の後は空けません。

入力サンプル

出力サンプル

イー・サン・ウー

コード

#include<stdio.h>
int main()
{
	char *pinyin[]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
	int sum = 0;
	char n;
	int i = 0;
	scanf("%s",n);
	while (n[i] !=0)
	{
		int num = n[i] - '0';
		sum += num;
		i++;
	}
	int weishu[4];
	int index = 0;
	while (sum / 10 !=0)
	{
		weishu[index] = sum%10;
		sum = sum / 10;
		index++;
	}
	weishu[index] = sum;
	for (int j = index; j >= 0;j--)
	{
		printf("%s",pinyin[weishu[j]]);
		//最後の桁でない場合は、別のスペースを出力する。
		if(j!=0){
			printf(" ");
		}
		
	}
	return 0;
}

を渡したいです。

"答えは正しいです "は、自動問題審査員によって与えられる最も喜ばれる回答の1つです。この問題はPATの「正解」ギブアップの一つです。システムは読み込まれた文字列が次の条件を満たしていれば「正解」と出力し、そうでなければ「不正解」と出力します。「不正解

正解」を得る条件は

xPATxのような文字列は、xが空の文字列または文字Aのみからなる文字列のいずれかである「正解」をもたらします。aPbTcが正しいなら、aPbATcaも正しい。ここで、a,b,cは空文字列か文字Aのみからなる文字列。では、どの文字列が「正解」に値するかを判定するPATの自動判定器を書いてください。

入力フォーマット

各テスト入力には 1 つのテストケースが含まれます。最初の行には、テストする文字列の数を正の整数 n で指定します。次の行は、空白を含まない 100 文字までの文字列です。

出力フォーマット

各文字列のテスト結果は1行を占め、その文字列が「正解」を得ることができればYESを、そうでなければNOを出力します。

入力サンプル

8 PAT PAAT AAPATAA AAPAATAAAA xPATx PT Whatever APAAATAA

出力サンプル

はい はい はい はい いいえ いいえ いいえ いいえ

コード

#include <stdio.h>
#include <string.h>
int checkIsPAT(char *str);
int main() {
 int n;
 scanf("%d", &n);
 getchar();
 for (int i = 0; i < n; i++) {
 char str;
 gets(str);
 if (checkIsPAT(str)) {
 printf("YES
");
 } else {
 printf("NO
");
 }
 }
 return 0;
}
int checkIsPAT(char *str) {
 int len = strlen(str);
 if (len < 3) {
 return 0;
 }
 int pCount = 0;
 int aCount = 0;
 int tCount = 0;
 for (int i = 0; i < len; i++) {
// 最初の条件が満たされるかチェックする
 if (str[i] == 'P') {
 pCount++;
 } else if (str[i] == 'A') {
 aCount++;
 } else if (str[i] == 'T') {
 tCount++;
 } else {
// PAT以外の文字を含む場合は0を返す。
 return 0;
 }
 }
// P T 1つしかなく、Aの数が少なくとも1でなければならない。
 if (pCount == 1 && tCount == 1 && aCount) {
 for (int i = 0; i < len; i++) {
 //3つ目の条件が満たされるかどうか、つまり、Pの左側にあるAの数をチェックする。 = PT中間Aの数 * T右のAの数
 if (str[i] == 'P') {
 int countA1 = i;
 for (int j = i + 1; j < len; j++) {
 if (str[j] == 'A') {
 for (int k = j + 1; k < len; k++) {
 if (str[k] == 'T') {
 int countA2 = k - i - 1;
 int countA3 = len - k - 1;
 if (countA1 * countA2 == countA3) {
 return 1;
 }
 }
 }
 }
 }
 }
 }
 }
 return 0;
}

結果のランキング

n人の生徒の名前、生徒番号、成績を読み込み、それぞれ最高と最低の成績を持つ生徒の名前と生徒番号を出力します。

入力フォーマット

各テスト入力には、以下の形式で1つのテストケースが含まれています。

1行目:正の整数n 2行目:最初の生徒の名前、番号、学年 3行目:2番目の生徒の名前、番号、学年 ... ... ...n+1行目: n番目の生徒の名前、番号、学年。

名前と学生番号は10文字以下の文字列で、評点は0から100の整数です。ここで、テストケースに含まれる2人の学生が同じ評点を持つことはありません。

出力フォーマット

各テストケースについて、2 行を出力してください。1 行目は最高評点の生徒の名前と生徒番号、2 行目は最低評点の生徒の名前と生徒番号です。

入力サンプル

3 ジョー Math990112 89 マイク CS991301 100 メアリー EE990830 95

出力サンプル

マイク CS991301 ジョー Math099112

コード

#include<iostream>
#include<string>
using namespace std;
int main() {
	int n;//入力数を記録する
	string name;//生徒の名前を記録する
	string nick;//学生番号を記録する
	int core;//学校番号を記録する
	int mincore=0,maxcore=0,min=0,max=0;//最低点、最高点、どの生徒が最高点、どの生徒が最低点かを記録する。
	cin >> n;
	for (int i = 0; i < n; i++)
	{
		cin >> name[i] >> nick[i] >> core[i];
	}
	mincore = maxcore = core[0];
	min = max = 0;
	for (int i = 1; i < n; i++)
	{
		if (mincore > core[i]) {//最も低いスコアを検索する。
			mincore = core[i];
			min = i;
		}
		if (maxcore < core[i]) {//最高得点を検索する。
			maxcore = core[i];
			max = i;
		}
	} 
	cout << name[max] <<" " << nick[max] << endl;
	cout << name[min] << " " << nick[min] << endl;
	cin >> n;
	return 0;
}

推測を続けます

カラシュ予想については1001年に説明があります。このトピックでは、状況は少し複雑です。

カラッツ予想を検証する場合、計算の繰り返しを避けるために、再帰中に遭遇する各数を記録することができます。例えば、n=3の検証で3, 5, 8, 4, 2, 1の計算が必要な場合、n=5, 8, 4, 2を検証するとき、この4つの数は3の検証ですでに遭遇しており、5, 8, 4, 2は3によって「覆われる」数であると主張されているので、計算を繰り返すことなく直接カラッツ予想の真偽を決定することができます。5,8,4,2を3が「カバーする」数と呼びます。ある級数の中の数nが、その級数の中の他の数でカバーされない場合、その数を「キー数」と呼びます。

今、検証されるべき一連の数字が与えられたとき、残りの数字の検証を繰り返す必要がないように、いくつかの重要な数字だけを検証する必要があります。あなたの仕事は、これらのキーとなる数字を見つけ、降順に出力することです。

入力フォーマット

各テスト入力には、1 行目に正の整数 K、2 行目に空白で区切られた検証すべき K 個の異なる正の整数 n の値を持つ 1 つのテストケースが含まれます。

出力フォーマット

各テストケースの出力は1行を占め、キーの番号が降順に出力されます。数字はスペース1個で区切られますが、1行の最後の数字の後にはスペースはありません。

入力サンプル

6 3 5 6 7 8 11

出力サンプル

7 6

コード

#include <iostream>
#include <algorithm>
using namespace std;
int cmp(int a, int b) {
 return a > b;
}
int main() {
 int n;
 cin >> n;
 int *a = new int[n];
 for (int i = 0; i < n; ++i) {
 cin >> a[i];
 }
 int t;
 sort(a, a + n, cmp);
 for (int i = 0; i < n; ++i) {
 t = a[i];
 while (t != 1 && t != 999) {
 if (t % 2 == 0) {
 t = t / 2;
 } else {
 t = (t * 3 + 1) / 2;
 }
 for (int j = 0; j < n; ++j) {
 if (t == a[j] && j != i)
 a[j] = 999;
 }
 }
 }
 sort(a, a + n, cmp);
 int temp = 0;
 for (int k = n - 1; k >= 0; --k) {
 if (a[k] != 999)
 temp = k;
 }
 for (int l = temp; l < n - 1; ++l) {
 cout << a[l] << " ";
 }
 cout << a[n - 1];
 delete[] a;
 return 0;
}

整数を異なるフォーマットで出力

Bは "100"、Sは "10"、nは "12.......nは0以外の数字nを表し、3桁以下の正の整数を出力するように書式を変更します。例えば、234 は、2 百、3 十、1 桁目に 4 があるので、BBSSS1234 と出力されます。

入力フォーマット

各テスト入力には 1 つのテストケースが含まれ、正の整数 n が与えられます。

出力フォーマット

各テストケースの出力は1行を占め、所定のフォーマットでnを出力します。

入力サンプル1

432

出力サンプル1

BBSSS3214

サンプル2を入力します:

23

サンプル2を出力します:

SS321

コード

#include<stdio.h>
int main()
{
	int n,i,x,y;
	scanf("%d",&n);
	x=n/100;
	for(i=0;i<x;i++)
		printf("B");
	y=(n-100*x)/10;
	for(i=0;i<y;i++)
		printf("S");
	n=(n-100*x-10*y);
	for(i=1;i<=n;i++)
		printf("%d",i);
	return 0;
}
Read next

Array.fill()を使ってオブジェクトを埋める際の問題点

これではうまくいかないので、mapを使ってデータを埋めます。 最終的な解決策は、まず配列の各項目をnullで埋めて、配列が長さだけでなくデータ項目を持つようにし、次にmapを使って各項目をnewObject()で置き換えます。

Jun 5, 2020 · 1 min read