C言語アルゴリズム学習(ポインター、構造、数学的計算)

この記事は7つのサンプル質問から始まり、今日のアルゴリズムについての私の学習について説明します

A-マヤ暦

問題の言い換え

先週末、MAYa教授は古代マヤについて大きな発見をしました。教授は、古代の結び目ロープ(マヤ人が物事を記録するために使用した道具)から、マヤ人が1年365日あるハーブ暦を使用していることを発見しました。ハアブ暦は年間19か月です。最初の18か月は、毎月20日です。月の名前は、pop、no、zip、zotz、tzec、xul、yoxkin、mol、chen、yax、zacです。 、ceh、mac、kankin、muan、pax、koyab、cumhu。これらの月の日付は0から19で表され、Haabカレンダーの最後の月はuayetと呼ばれ、5日しかなく、0から4で表されます。マヤ人は、日付が最も少ない月を不運だと考えました。今月は、法廷は開かれず、人々は取引に従事せず、家の掃除さえしません。
宗教上の理由から、マヤは別の暦も使用しました。この暦の中央はツォルキン暦(聖年)と呼ばれます。年は13の異なる期間に分割され、各期間は20日で、各日は数字を使用します。単語と組み合わせた形で表現されます。使用する数字は1〜13で、 20語使用されています。imix、ik、akbal、kan、chicchan、cimi、manik、lamat、muluk、ok、chuen、eb、ben、ix、mem、cib、 caban、eznab、canac、ahau。注:年の各日には明確で一意の説明があります。たとえば、年の初めの日付は次のように説明されます:1 imix、2 ik、3 akbal、4 kan、5 chicchan、6 cimi、7 manik、8 lamat、9 muluk、10ok、11 chuen、12 eb、13 ben、1 ix、2 mem、3 cib、4 caban、5 eznab、6canac、7 ahau、8 imix、9 ik、10 akbal...つまり、数字と単語は独立
してサイクルで使用されます。
ハアブ暦とツォルキン暦の年は0、1、...の数字で表され、0という数字は世界の始まりを示します。したがって、初日は次のように表されます
。•
Haab:0。pop 0
Tzolkin:1 imix0 MAYa教授がHaabカレンダーをTzolkinカレンダーに変換するプログラムを作成するのを手伝ってください。

入る

•Haabカレンダーのデータは、次のメソッドで表されます。
•NumberOfTheDay。MonthYear(日付。MonthYear)
•入力の最初の行は、変換されるHaabカレンダーの日付のデータ量を示します。後続の各行
は日付を表し、年数は5000未満です。

出力

•ツォルキンカレンダーのデータは、次のように表されます。
•数値NameOfTheDay年(日番号日名年番号)
•最初の行は、出力される日付の数を表します。以下の各行は、入力データの対応するツォルキンカレンダーの日付を表します。

問題解決のアイデア

ハアブの年表の下で合計日数を見つけて、それをツォルキンの年表に変換します。
haabメモリアルメソッドは毎月0からカウントされることは注目に値します。
最初に2つの文字列関数haabとtzolinを設定して月名と月番号の変換を完了し、次に構造配列を設定して時間を記録し、最後に日数の合計を計算してtzolkin出力に変換します。

ソースコード

#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
const int N = 5000;
struct data {
    
    
	int year,day;
	string month;
} p[N];
int n;
int main() {
    
    
	string haab[] = {
    
    "pop","no","zip","zotz","tzec",
	                 "xul","yoxkin","mol","chen","yax","zac","ceh",
	                 "mac","kankin","muan","pax","koyab","cumhu","uayet"
	                };
	string tzo[] = {
    
    "imix","ik","akbal","kan","chicchan","cimi",
	                "manik","lamat","muluk","ok","chuen","eb","ben","ix",
	                "mem","cib","caban","eznab","canac","ahau"
	               };
	cin>>n;
	cout<<n<<endl;
	for(int i = 1; i <= n; ++i) {
    
    
		scanf("%d. ",&p[i].day);
		cin>>p[i].month;
		cin>>p[i].year;
		int year,month,day,t,cnt;
		for(int j = 0; j<19; ++j) {
    
    
			if(p[i].month==haab[j]) {
    
    
				t = j;
				break;
			}
		}
		cnt = p[i].year*365+t*20+p[i].day;//计数共过了多少天
		year = cnt/260;// 按tzolki算经历了多少年
		cnt = cnt%260;//算出剩余总天数
		day =cnt%13+1;
		month = cnt%20;
		cout<<day<<" "<<tzo[month]<<" "<<year<<endl;
	}
	return 0;
}

B-外交ライセンス

問題の言い換え

外交支出を最小限に抑えるために、世界中の国々が次のように議論しています。世界には2つ以上の国があり、一部の国は(一連の)外交官を通じて互いにコミュニケーションをとることができないため、各国が最大で1つの国と外交関係を維持するだけでは不十分です。
•この質問は、各国が最大で他の2か国と外交関係を維持していることを前提としています。すべての国を平等に扱うことは、書かれていない外交慣行です。したがって、各国は他の2カ国と外交関係を維持しています。
•国際的な地形学者は、このニーズに適した構造を提案しています。彼らは、各国が隣国との外交関係を確立できるように、各国を輪になって配置します。現実の世界では、ある国の外務省はその国の首都にあります。簡単にするために、この質問では、首都の位置が2次元平面上の点であると想定しています。外交関係を維持している国の外務省を直線で結ぶ
と、多角形になります。
•今、私たちは二国間の二国間外交会議の場を設定する必要があります。同様に、外交上の理由から、両国の外交官はその場所まで同じ距離を移動する必要があります。効率を上げるためには、走行距離をできるだけ短くする必要があります。二国間外交会議に備えてください。
•入力
•入力はいくつかのテストケースを提供します。各テストケースは最初に番号nを与えます。これは、nか国が関与していることを意味します。この質問は、n3が奇数であることを前提としています。次に、外務省の場所を示すために、x座標とy座標のnペアが与えられます。外務省の座標は、絶対値が1012未満の整数です。国の順序は、入力に表示される順序と同じです。さらに、リストでは、最初の国が最後の国の隣国です。
•出力
•各テストケースについて、最初にテストケースの国の数(= n)を出力し、次に国間の二国間外交会議の場所のx座標とy座標を指定します。出力会議の場所の順序は、入力で指定された順序と同じである必要があります。上位2か国の待ち合わせ場所から始まり、最後の2か国の待ち合わせ場所まで続き、最後にn番目の国と1番目の国の待ち合わせ場所が出力されます。

(簡単に言えば、2つの隣接する数値の中点を計算します)

問題分析

次のアイデアに従ってください。

  1. x座標とy座標を記録する構造を定義します
  2. 構造体を最後に設定し、新しい番号があるときはいつでも最後に読み込みます。
  3. 最後の平均値と、前の数値セットと出力を記録する構造変数を計算します
  4. Now = last
    は、最初から最後までの比較が必要なため、最初の番号に対して特別に処理する必要があります。最初のグループ番号を記録するために、f構造体irstが設定されます。

ソースコード:

#include<cstdio>
#include<iostream>
using namespace std;
struct point {
    
    
	long long int x;
	long long int y;
};
int main() {
    
    
	struct point now,first,last;
	int n=0;
	while(~scanf("%d",&n)){
    
    
		printf("%d ",n);
		cin >>first.x >>first.y;
		now=first;
		for(int i=1;i<n;i++)
		{
    
    
			cin >>last.x >>last.y ;
			printf("%.6f %.6f ",(last.x+now.x)/2.0,(last.y+now.y)/2.0);
			now=last;
		}
		now=first;
		printf("%.6f %.6f\n",(last.x+now.x)/2.0,(last.y+now.y)/2.0);
	}`在这里插入代码片`
	return 0;
	}

この質問では、次の間違いを犯しました
。1。出力形式が浮動小数点数であり、型変換を強制しておらず、2と小数点
2.xがなく、yが次のように定義されていないロングロングタイプ。

次の2つの質問はポインタの使用です

C.「アコーディオン」の忍耐

問題の言い換え

「アコーディオン」の忍耐ゲームを真似てください。ルールは次のとおりです
。•プレイヤーは、カードのデッキを左から右に、重ならないように1枚ずつ配ります。トランプが左から1番目または左から3番目のカードと一致する限り、このトランプを一致したカードの上に移動します。いわゆる2枚のカードの一致は、2枚のカードが同じ値(数字または文字)または同じスーツを持っていることを意味します。カードを移動するときはいつでも、カードが左に移動し続けることができるかどうかを確認し、毎回デッキの一番上にあるカードのみを移動します。このゲームでは、2枚の山を1枚の山に変えることができます。ルールに従って、右の山から左の山にカードを1枚ずつ移動して1枚の山にすることができます。このゲームはカードをできるだけ左に動かします。最後にデッキが1つしかない場合は、プレイヤーが勝ちます。
•ゲーム中に、プレイヤーは一度に複数の選択肢がある状況に遭遇する可能性があります。両方のカードが移動できる場合、一番左のカードが移動します。カードが1ポジション左または3ポジション左に移動できる場合は、カードを3ポジション移動します。

入る

•カードが配られる順番を入力します。各テストケースは1対の行で構成され、各行は1つのスペース文字で区切られた26枚のカードを提供します。入力ファイルの最後の行では、最初の文字として#が指定されています。各トランプは2文字で表されます。最初のキャラクターは額面(A =エース、2-9、T = 10、J =ジャック、Q =クイーン、K =キング)で、2番目のキャラクターはスーツ(C =クラブ(梅花)、D =ダイヤモンド(正方形)、H =ハート(ハート)、S =スペード(スペード))。

出力

•入力の行のペアごとに(トランプのデッキの52枚のカード)、1行を出力し、対応する入力行が再生された後、トランプの各山に残っているカードの数を示します。
この質問にはエアコンがないのでスキップしてください

D-壊れたキーボード

問題の言い換え

悪いキーボードで長いテキストを入力しています。このキーボードの問題は、テキストを入力すると、「ホーム」キーまたは「終了」キーが自動的に押されることがあることです。あなたはテキストだけに焦点を合わせ、ディスプレイをオンにすることさえしないので、この問題に気づいていません。入力が終了したら、モニターの電源を入れて、画面にテキストを表示します。中国語では、それを悲劇と呼びます。悲劇のテキストを見つけてください。

入る

•いくつかのテストケースを入力します。各テストケースは、少なくとも1つ、最大100,000文字、アンダースコア、および2つの特殊文字「[」と「]」を含む行です。「[」は「ホーム」キーを意味し、「]」は「終了」キーを意味します。入力はEOFで終わります。

出力

•各テストケースについて、画面上のテキストの出力悲劇
サンプル入力
This_is_a_ [Beiju] _TEXT
[] [] [] Happy_Birthday_to_Tsinghua_University
サンプル出力
BeijuThis_is_a__text
Happy_Birthday_to_Tsinghua_University

この質問にもACがなく、評価せず、スキップします

E-衛星

問題の言い換え

ここに画像の説明を挿入

入る

•入力には、1つ以上のテストケースが含まれています。
•テストケースごとに1行で、2つの整数sとa、および文字列「min」または「deg」を示します。ここで、sは人工衛星と地表の間の距離、aは2つの人工衛星の間の距離です。地球の中心に角度。単位として分( ')または度(◦)で。入力は、ポイントと度の両方を提供しません。

出力

•テストケースごとに、2つの衛星間の弧距離と線形弦距離をキロメートル単位で示す1行を出力します。距離は浮動小数点数で、小数点以下6桁を格納します。

問題分析

数学計算の問題は、問題を理解し、数式をリストする必要
ここに画像の説明を挿入
があります。360°の減算を使用して、180°を超える角度を処理できます

#include<iostream>
#include<cmath>
using namespace std;
double s,a;
string op;
//acos(-1)表示Π
int main() {
    
    
	while(cin >> s >> a >> op) {
    
    
		if(op == "min") a /= 60;
		if(a > 180) a = 360 - a;
		double arcdist = 2*acos(-1)*(s+6440.0)*a/360;
		double chord_dist = (s + 6440.0)*sin(a*acos(-1)/360)*2;
		printf("%.6lf %.6lf\n",arcdist,chord_dist);
	}
	return 0;
}

G-円周

問題の言い換え

•円の直径を知っている限り、円の円周を計算するのは簡単な作業のようです。しかし、あなたが知らない場合はどうなりますか?平面上の3つの非同一線上の点のデカルト座標を与えます。あなたの仕事は、これらの3点と交差する唯一の円の周囲長を計算することです。

入る

•入力には1つ以上のテストケースが含まれ、各テストケースは3点の座標を表す6つの実数x1、y1、x2、y2、x3、y3を含みます。これらの3点で決まる直径は100万を超えません。入力はファイルの終わりで終了します。

出力

•テストケースごとに、1行を出力し、3点で決定される円の円周を表す実数を入力します。出力円周は小数点以下2桁まで正確です。Piの値は3.141592653589793です。

問題分析

ヘレン式、私の神
ここに画像の説明を挿入

ソースコード

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
double xa,ya,xb,yb,xc,yc,p;
double getDistance(double x,double y,double xx,double yy) {
    
    
	return sqrt(pow(x-xx,2)+pow(y-yy,2));
}
int main() {
    
    
	while(cin >> xa >> ya >> xb >> yb >> xc >> yc) {
    
    
		double a = getDistance(xa,ya,xb,yb);
		double b = getDistance(xb,yb,xc,yc);
		double c = getDistance(xa,ya,xc,yc);
		double p = (a+b+c)/2;
		double s = sqrt(p*(p-a)*(p-b)*(p-c));
		double d = a*b*c/2.0/s;
		printf("%.2f\n",d*acos(-1.0));
	}
	return 0;
}

総括する

リンクリストの把握が不十分で、使い方も不十分で、Cの共通関数ライブラリや関数に慣れていないので、改善する必要があります。

おすすめ

転載: blog.csdn.net/seekerzhz/article/details/112853063