ブログ移住計画その1~AWSでインストールの下準備~
前回の記事であげたように、この夏休み中にWordPressにブログを移行しようと考えています。
で、今日はその初回。
ただ単にWordPressをインストールするだけならどこかサーバを借りてデフォルトでインストールすれば問題ないのですが、
せっかくなので自称エンジニア(?)らしく技術的な部分も取り入れつつやってみます。
今回のWordPressインストールではAnsibleを使ってAWS(EC2)上に立てたいなと思います。
構成図はこんな感じ。
セキュリティにも考慮して、 踏み台経由でのSSHログインでWordPress用のDBにするMySQLサーバはPrivateのサブネット内に入れておきます。
AWS上でインストールの下準備
VPCの構築
まずは、VPCを作ります。
項目 | 値 |
---|---|
名前 | wordpress-vpc(仮名) |
IPv4 CIDR | 10.0.0.0/16 |
サブネットの構築
次にサブネットです。
今回は踏み台+wordpress用のサブネットとDB用のサブネットを作ります。
DMZサブネット
項目 | 値 |
---|---|
名前 | dmz(仮名) |
VPC | wordpress-vpc |
アベイラビリティゾーン | 自由に設定 |
IPv4 CIDR | 10.0.1.0/24 |
設定後、自動割当IP設定の変更で
- パブリックIPv4アドレスの自動割当を有効にする
にチェックをつけておく
Privateサブネット
項目 | 値 |
---|---|
名前 | private(仮名) |
VPC | wordpress-vpc |
アベイラビリティゾーン | 自由に設定 |
IPv4 CIDR | 10.0.2.0/24 |
インターネットゲートウェイの作成
次にDMZ内のサーバ(インスタンスに)インターネットから直接アクセスさせるためのゲートウェイを作成
NATゲートウェイの作成
DMZ内のインスタンスとインターネットは接続できるのですが、
DB側インスタンスにはインターネットと接続できません。
セキュリティ的にはOKなんですけど、
これだとMySQLをインストールしたいときとかメンテナンス、アップデートするときにちょっとやっかい。
なので、
インターネット→プライベートサブネットは✕
プライベートサブネット→インターネットは○
みたいなことをうまいことしてくれるNATゲートウェイを作っておきます。
(これ結構金かかるんですよね・・・なので必要なときだけたてて、いらないときは削除予定)
NATゲートウェイの作成から、
1. サブネットでDMZサブネットのIDを指定
2. ElasticIPを設定
ルートテーブルを設定
NATゲートウェイ・インターネットゲートウェイとサブネットを紐付けるために、 ルートテーブルを作成
ルートテーブルの作成から、名前とVPCを指定して2つ作成
DMZサブネット
- サブネットの関連付けでDMZサブネットの関連付けにチェック
- ルートを編集し、以下を追加
送信先 | ターゲット |
---|---|
0.0.0.0/0 | インターネットゲートウェイID |
Privateサブネット
- サブネットの関連付けでPrivateサブネットの関連付けにチェック
- ルートを編集し、以下を追加
送信先 | ターゲット |
---|---|
0.0.0.0/0 | NATゲートウェイのID |
SSHの鍵を作成
サーバを立てる下準備の最後として公開鍵作ります。
というのも、基本的にAWS上のサーバにアクセスするときは公開鍵使うんですけど、AWSのサーバ立てるときに自動で落ちてくる鍵はパスフレーズなしなんですよね。。。
そんな鍵を使いたくないので、自作で作ってインポートさせます。
ssh-keygen -t rsa -b 4096 -f <鍵名>.pem
本当は、
ssh-keygen -t ed25519 -f <鍵名>.pem
ed25519暗号で生成した鍵を使いたかったけど、なぜかインポート時にエラーが出た
暗号はED25519は意識高すぎ、高杉くんらしい。
暗号鍵参考URL
AWSのEC2からキーペアに移動して、
キーペアインポートから作ったキーをインポート
インスタンス作成
これで心おきなくインスタンスを作成 ひとまず3台立てる
- 共通項目
- OSはCentOS7
- SSH鍵はさっき作ったものを使用
- 踏み台サーバ
- Wordpressサーバ
- MySQLサーバ
- t2.small
- SSD30GB
- サブネットはPrivateサブネット
- セキュリティグループはDMZサブネットに対して公開
これでサーバ建てられた
SSHログインの確認
3台のサーバにSSHでログインできるか確認します。 ただ、踏み台以外のサーバは直接SSHできないので、踏み台経由でログインするように設定します。
Macの場合:
# ~/.ssh/configファイルの中に記述 Host wp-bustion HostName <踏み台インスタンスのパブリックIP> User centos Port 22 GatewayPorts yes IdentityFile ~/.ssh/<公開鍵のファイル> Host wordpress HostName <WordPressインスタンスののプライベートIP> User centos Port 22 GatewayPorts yes ProxyCommand ssh -CW %h:%p wp-bustion IdentityFile ~/.ssh/<公開鍵> Host wp-mysql HostName <MySQLインスタンスのプライベートIP> User centos Port 22 GatewayPorts yes ProxyCommand ssh -CW %h:%p wp-bustion IdentityFile ~/.ssh/<公開鍵ファイル>
ssh-addコマンドで毎回パスフレーズを入力しなくていいように設定
ssh-add ~/.ssh/<公開鍵ファイル>
実際にログインして確認
ssh wp-bustion ssh wordpress ssh wp-mysql
ログイン成功。
踏み台サーバのSSHポートを変更する
ここは賛否両論あるみたいなんですが、せっかくなのでポート変えておきます。
###踏み台インスタンスにログイン ### /etc/ssh/sshd_configを開いて以下を編集 ###Port22 Port <新しいポート番号>
このあと
systemctl restart sshd
で再起動して、一旦ログアウト。
ローカルで~/.ssh/configのところで、
Host wp-bustion HostName <踏み台インスタンスのパブリックIP> User centos Port <新しいポート番号> GatewayPorts yes IdentityFile ~/.ssh/<公開鍵のファイル>
と編集。
再度SSHログイン。
うまくいった。
これで下準備完了
夏休みブログ移住計画
今日はあくまで宣言だけするよ。
そろそろお盆がきますね。
自分の会社も例にもれずお盆休みなるものがあります。
こういう長期的な休みの前になると、どこに遊びに行こうかとか、
誰とご飯食べにいこうかと考えるのもあるのですが、
その一方でなにか勉強しようかなーと考えるのも結構好きなんです。
で、普段はどちらかというとインプットよりでひたすら技術書含め本を読むことが多いのですが、
たまにはこれまでのアウトプットをやりたいなと思い、いろいろ考えた結果、このブログを移住させようと考えました。
(といってもそんなにこのブログであれこれ書いてないですけど・・・)
移住計画概要
- 概要
- WordPressにブログを移住
- 目的
- 目標
- ひとまず夏休み中(19日まで)に移住完了させたい
- 今年中にデータの基盤やら分析やらできたらいいな
- 手順
とこんな感じ。
ま、とりあえず書けば自分の重い腰もあがるやろうということで今日はあくまで宣言のみ。 明日からやってみる。
Ubuntu16にCDH6(Beta)をManagerなしでインストール
最近Clouderaの動向をウォッチしていなかったのですが、 知らぬ間にCDH6がリリースされていました。
https://www.cloudera.com/documentation/enterprise/6/release-notes/topics/rg_cdh_6_release_notes.html
※まだベータ版らしいです。
CDH6はHadoop3.0.0やSparkも2系がデフォルトで入っているようで、 新しい機能を試してみるのにサクサク入れられるディストーションとしても使えそうです。
というわけで、ひとまずデフォルトでインストールしてみました。 CDH5版インストール方法はこちらの記事から
というより前記事とほとんどインストール方法は変わりません。
ちなみにCloudera Managerを使ったのインストールはこちらから(めっちゃ簡単)
環境
Javaのインストール
ひとまず、java8を先に入れて、PATHを通しておきます。
sudo add-apt-repository ppa:webupd8team/java sudo apt-get update sudo apt-get -y install oracle-java8-installer cat << EOF >> ~/.bashrc JAVA_HOME=/usr/lib/jvm/java-8-oracle PATH=$PATH:$JAVA_HOME/bin export JAVA_HOME export PATH EOF source ~/.bashrc
cdh.listファイルの作成
/etc/apt/sources.list.dの中にcdh.listというファイルを作成
cd /etc/apt/sources.list.d sudo touch cdh.list ## vimやEmacsなどでcdh.listの中に以下のコマンドを入力 deb [arch=amd64] https://archive.cloudera.com/cdh6/6.0.0-beta1/ubuntu1604/apt xenial-cdh6.0.0-beta1 contrib deb-src https://archive.cloudera.com/cdh6/6.0.0-beta1/ubuntu1604/apt xenial-cdh6.0.0-beta1 contrib
Hadoopのリポジトリ登録
sudo wget https://archive.cloudera.com/cdh6/6.0.0-beta1/ubuntu1604/apt/archive.key sudo apt-key add archive.key
Hadoopインストール&起動
あとは素直にHadoopを入れて動かすだけ。
sudo apt update sudo apt-get install -y hadoop-conf-pseudo sudo -u hdfs hdfs namenode -format sudo systemctl start hadoop-hdfs-namenode hadoop-hdfs-datanode hadoop-hdfs-secondarynamenode sudo /usr/lib/hadoop/libexec/init-hdfs.sh sudo systemctl restart hadoop-hdfs-namenode hadoop-hdfs-datanode hadoop-hdfs-secondarynamenode sudo systemctl start hadoop-yarn-resourcemanager hadoop-yarn-nodemanager
結論
やっぱりCloudera ManagerとCloudera Directorは正義。
なるべくお金をかけずにお手軽運用でサーバを扱う(検証、テスト用)
なるべくお金をかけずにお手軽運用でサーバを扱う(検証、テスト用)1,2年前にまとめていたけど、
下書きで残しっぱなしだったので、今更載せておきます。
前ふり
AWS等クラウドでサーバを立てる時に気になるお金。
なるべく課金を減らすために必要なときだけ立てて、
いらなければ落とすなんてことをしますよね。
でも落とした後に起動するとやっかいなのがIPアドレスの変更。
毎回毎回アドレスが変わってしまうとssh config等の設定を変えないといけなかったりして面倒なんですよね。
かといってElasticなIPを使うとそれでもお金がかかってしまうので嫌だ。。。
というわけで、なるべくお金をかけずにかつ設定をなるべく変えないでサーバを扱う方法を自分なりに試行錯誤してみたやつです。
※今回の例はあくまで検証や遊びでサーバを立てて使う人用の方法です。本番システムでの利用は推奨しません。
やること
- VPCを作成
- パブリックサブネットとプライベートサブネットを立てる
- インターネットからパブリックサブネットにアクセスさせる設定
- パブリックサブネットに踏み台サーバを立てる
- プライベートサブネットに検証サーバを立てる
- ssh configで踏み台経由でサーバにアクセスする設定を行う
- ssh <設定名>でいつでもアクセスできる やっていることのほとんどはAWSEC2のデザインパターンとかでよくみるやつです。
VPCの作成
まずは、VPCを作成します。
AWSのユーザーコンソールからVPCに移動
設定項目 | 設定値 |
---|---|
名前タグ | 適当な名前で |
IPv4 CIDRブロック | なんでもいいけどVPCにいっぱいサーバを立てるなら10.0.0.0/16が順当かと |
IPv6 CIDRブロック | ブロックはなしで |
テナンシー | デフォルトでOK |
パブリックサブネットとプライベートサブネットを立てる
続いてサブネットを作ります。
ユーザーコンソールからVPC -> サブネットに移動。
サブネットではインターネット経由でアクセスできるパブリックサブネットとプライベートサブネットを設定します。
- パブリックサブネット側
設定項目 | 設定値 |
---|---|
名前タグ | 適当な名前で |
VPC | さっき作成したVPC名を指定 |
アベイラビリティーゾーン | 今回は特に指定なしでOK |
IPv4 CIDRブロック | VPCで設定したブロック内で範囲を指定。今回は10.0.1.0/24としておく。 |
- プライベートサブネット側
設定項目 | 設定値 |
---|---|
名前タグ | 適当な名前で |
VPC | さっき作成したVPC名を指定 |
アベイラビリティーゾーン | 今回は特に指定なしでOK |
IPv4 CIDRブロック | VPCで設定したブロック内で範囲を指定。今回は10.0.2.0/24としておく。 |
インターネットからパブリックサブネットにアクセスさせる設定
ここは大事なところ。
2つサブネットを作成した後に、パブリックサブネットのみ選択して、サブネットのアクション-> 自動割り当てIPの設定変更 に飛ぶ
そこで、 パブリックIPv4アドレスの自動割り当てを有効にする にチェック。
これをやっとかないと踏み台サーバ立てても外部からサーバにアクセスするための外部IPを発行してくれません。
次にやるのはインターネットとパブリックサブネットをつなぐゲートウェイ(窓口みたいなもの)の設定
- VPC -> インターネットゲートウェイに移動
- インターネットゲートウェイの作成を押して文字通り作成(名前は適当に)
- さっき作ったゲートウェイを選択して、 アクション->VPCのアタッチを選択
- VPCでさっき作ったVPCを選択してアタッチ
- VPC -> ルートテーブルに移動
- 作ったVPCに紐づくルートテーブルを選択。
- 下部にあるルートタブを選択して編集。
- 別のルートを追加を選択。以下のように設定
送信先 | ターゲット |
---|---|
0.0.0.0/0 | さっき作ったゲートウェイの名前 |
これでできました。
パブリックサブネットに踏み台サーバを立てる
ここから踏み台サーバを立てます。
サーバの立て方は基本的な方法と同じなので割愛。
一般的な立て方と違うのは以下の点。
- インスタンスのタイプはt2.nano(踏み台用途なので and 24時間稼働を想定してなるべくお金がかからないように)
- インスタンスの詳細の設定にて
- ネットワーク -> 作ったVPCの名前
- サブネット -> パブリックサブネットの名前
プライベートサブネットに検証サーバを立てる
今度はプライベート側に実際に使用するサーバを立てます。
こちらも基本的な立て方は同じ。
変更点は以下の点
- インスタンスの詳細の設定にて
- ネットワーク -> 作ったVPCの名前
- サブネット -> プライベートサブネットの名前
- セキュリティグループは基本的に全開放でも問題ないが、気にされる方は必要なポートをパブリックサブネットのIPに指定するとよし。
ssh configで踏み台経由でサーバにアクセスする設定を行う
サーバが立てられたので、sshでつなぐ設定をします。 今回はmacを想定し、macの.ssh/configに設定をします。
# ~/.ssh/config Host humidai HostName <踏み台サーバのパブリックIP> User ubuntu #サーバによって変化 Port 22 #sshポート GatewayPorts yes IdentityFile ローカルマシン内で踏み台サーバの公開鍵が置いてある場所 Host server HostName <10.0.2.xxとなるIP> User ec2-user #サーバによって変化 Port 22 GatewayPorts yes ProxyCommand ssh -CW %h:%p humidai #humidaiは上記設定したHostの名前を指定 IdentityFile ローカルマシン内で検証サーバの公開鍵が置いてある場所 # ProxtCommandが踏み台サーバ経由でsshサクセスさせるためのコマンド
この設定をした後、
ssh server
とコマンドを入力すると、踏み台経由でアクセスできます。
しかも、検証サーバを一旦落として再度あげてもプライベートIPは変わらないので、そのままsshコマンドで入れます。
また、ポートフォワーディングしたい場合は、
# ~/.ssh/config #踏み台側 LocalForward 5432 localhost:5432 LocalForward 8080 localhost:8080 #サーバ側 LocalForward 5432 <サーバのプライベートIP>:5432 LocalForward 8080 <サーバーのプライベートIP>:8080
と設定すればOK
懸念事項
1 この構成にすると、サーバ側からインターネットにつなぐことができないので、wgetとかでファイルを落としたりすることはできません。
これについては別途NATインスタンスとかNATゲートウェイが必要になるのですが、いずれにしてもお金がかかる。。。。
なので、しょっちゅうインターネットにアクセスしないのであれば、ローカルマシンに対象ファイルを落としてscpコマンドで移動がよいかなと。
実際scpコマンドで移動させる場合でも
scp <移動させるファイル> server:/home/ec2-user
みたいな感じで簡単に移動できます。
2 この構成は踏み台サーバは常時稼働を想定しています。踏み台サーバはt2.nanoの最小構成なので、
$0.0058 /1 時間 -> 500円くらい/1ヶ月
が必要経費になります。
ただ、毎回毎回IPアドレスを変える手間とか、めんどくさくてサーバをずっと起動させることによる課金等を考えると決して高い値段ではないかなと。
終わりに
今回は最近良くやるAWSでの検証サーバ構築用のシステムを紹介しました。
上述したように、この構成は本番構成でもやるような部分も含まれていますので、特にAWS初心者の方はぜひチャレンジしてみるといいかもしれません。
ホントの最後に
間違いとか、わからないとこがあればコメントとかしていただければ!!
AtCoderに登録したら解くべき精選過去問10問の類題をC++で解いてみた(その6)
第7問(ABC 085 B - Kagami Mochi)の類題を解いていきます。
#include <iostream> #include <algorithm> #include <string> #include <set> using namespace std; int main() { string str; int length,i; set<char> alphabets; cin >> str; length = str.length(); for(i = 0; i<length; i++){ alphabets.insert(str[i]); } set<char>::iterator it; for(i = 'a';i <= 'z'; i++) { it = alphabets.find(i); if(it == alphabets.end()){ cout << (char)i << endl; return 0; } } cout << "None" << endl; return 0; }
- 各都市(数値で表される)を配列のキーとして用意しておき、2行目以降、その数値が出るたびにキーの値をインクリメントさせる
- 今思えばmap使わなくても普通の配列でできたかなと思うけど、、、まあいいか。
#include <iostream> #include <algorithm> #include <string> #include <map> using namespace std; int main() { int number_of_cities,number_of_roads,i,j,k; map<int,int> road_to_city; cin >> number_of_cities >> number_of_roads; for(i = 0 ; i< number_of_cities; i++) { road_to_city[i] = 0; } for(i = 0; i < number_of_roads;i++) { cin >> j >> k; road_to_city[j-1]++; road_to_city[k-1]++; } for(i = 0; i<number_of_cities;i++){ cout << road_to_city[i] << endl; } return 0; }
ABC 047 B - Snuke's Coloring 2 (ABC Edit)
- 一旦xとy座標を変数にした後、4象限(x軸の上側、下側、y軸の上側、下側)で隠される面積を割り出して、引き算する。
- 多分もっといい解法があるんだろうとは思うけど、今の実力ではこれがいっぱいいっぱいでした。
#include <iostream> #include <algorithm> #include <string> #include <map> #include <cmath> using namespace std; int main() { int x,y,i,j,k,l,number_of_coloring; int left_coloring_x = 0; int right_coloring_x = 0; int upper_coloring_y = 0; int lower_coloring_y = 0; cin >> x >> y >> number_of_coloring; for(i = 0; i < number_of_coloring;i++){ cin >> j >> k >> l; switch(l){ case 1: if(left_coloring_x < j){ left_coloring_x = j; } break; case 2: if(right_coloring_x < abs(x - j)){ right_coloring_x = abs(x - j); } break; case 3: if(lower_coloring_y < k){ lower_coloring_y = k; } break; case 4: if(upper_coloring_y < abs(y - k)){ upper_coloring_y = abs(y - k); } break; } } x = x - left_coloring_x - right_coloring_x; y = y - lower_coloring_y - upper_coloring_y; if(x <= 0 || y <= 0) { cout << 0 << endl; } else { cout << x * y << endl; } return 0; }
ABC 091 B Two Colors Card Game
- mapを用意
- 青いカードのときは文字列を見るたびににその文字をキーとして数値をインクリメント
- 赤いカードのときはその逆でその文字キーで数値をデクリメント
- あとはmapを上からキーを走査して、もっとも大きい数値を出力する
#include <iostream> #include <algorithm> #include <string> #include <map> #include <cmath> using namespace std; int main() { int i,number_of_bluecard,number_of_redcard; map<string,int> strs; string str; int max_yen = 0; cin >> number_of_bluecard; for(i = 0; i< number_of_bluecard; i++){ cin >> str; if(strs.find(str) == strs.end()){ strs[str] = 1; } else { strs[str]++; } } cin >> number_of_redcard; for(i = 0;i<number_of_redcard; i++){ cin >> str; if(strs.find(str) != strs.end() && strs[str] != 0 ){ strs[str]--; } } for(auto itr = strs.begin(); itr != strs.end(); itr++){ if(max_yen < itr->second) { max_yen = itr->second; } } cout << max_yen << endl; return 0; }
- 入力される数値をキーとして、各数値の出現回数をカウント
- 出現回数が多い順にキーをソート
- 規定されている数値の種類までカウントし、超えた場合は各キーに紐づく値を足し算していく
#include <iostream> #include <algorithm> #include <string> #include <map> #include <cmath> using namespace std; int main() { int i,ball,balls,num_ball_type; int ball_type[210000] = {0}; int counter = 0; int number_of_changed_type = 0; cin >> balls >> num_ball_type; for(i = 0; i < balls; i++){ cin >> ball; ball_type[ball]++; } sort(ball_type,ball_type+210000,greater<int>()); for(i = 0; i < 210000; i++){ if(ball_type[i] == 0){ break; } if(counter >= num_ball_type) { number_of_changed_type += ball_type[i]; } else { counter++; } } cout << number_of_changed_type << endl; return 0; }
AtCoderに登録したら解くべき精選過去問10問の類題をC++で解いてみた(その5)
最近サボってた。 ABC 083 B - Some Sumsの類題を解く。
ABC 080 B - Harshad Number + 与えられた数値を10で割っていきながら各位の値を足し算していく。 + その後、足し算した値で割り切れるかどうかを判定。
#include <iostream> using namespace std; int main() { int N,i,sum; cin >> N; i = N; while(i > 0){ sum += i % 10; i /= 10; } if(N % sum == 0){ cout << "Yes" << endl; } else { cout << "No" << endl; } return 0; }
ABC 090 B - Palindromic Numbers
- 与えられた数値の範囲内でループを回す
- ループごとに各位の値を分解して配列にわたす
- 一の位と一万の位、ならびに十の位と千の位の値が同じかどうか判定する
#include <iostream> using namespace std; int main() { int i,j,k,first,last,digits[10]; int counter = 0; cin >> first >> last; for(i = first; i <= last; i++){ j = i; k = 0; while(j > 0) { digits[k] = j % 10; cout << digits[k] << endl; j /= 10; k++; } if(digits[0] == digits[4] && digits[1] == digits[3]){ counter++; } } cout << counter << endl; return 0; }
続いて第6問(ABC 088 B - Card Game for Two )の類題。
- とりあえずソートさせて終わり。
- もうちょっとだけ補足すると、数値を大きい順番に並べ替えて順番に足し算していきます。
#include <iostream> #include <algorithm> using namespace std; int main() { int i,N,rods; int rod[60]; int maxlength = 0; int length = 0; cin >> N >> rods; for(i = 0; i < N; i++){ cin >> rod[i]; } sort(rod,rod+N,greater<int>()); for(i = 0; i < rods;i++){ length += rod[i]; } if(maxlength <= length) { maxlength = length; } cout << maxlength << endl; return 0; }
ABC 064 B - Traveling AtCoDeer Problem
- 最初は問題文を読んで??となったのですが、要するに与えられた値から最小と最大の値を抜き出してその差をとることだとわかってからはそこまで苦労しなかった。
- ソートしたほうが早かったかも。
#include <iostream> #include <algorithm> using namespace std; int main() { int i,N,coodinates[1100]; int maxcoodinate = 0; int mincoodinate = 0; cin >> N; for(i = 0; i < N; i++) { cin >> coodinates[i]; } mincoodinate = coodinates[0]; maxcoodinate = coodinates[0]; for(i = 1; i < N; i++) { if(coodinates[i] <= mincoodinate) { mincoodinate = coodinates[i]; } if(coodinates[i] >= maxcoodinate) { maxcoodinate = coodinates[i]; } } cout << maxcoodinate - mincoodinate << endl; return 0; }
ABC 042 B - Iroha Loves Strings
- 文字列のソート処理
- ソートさせたあと、順番に文字列連結させてます。
#include <iostream> #include <algorithm> #include <string> using namespace std; int main() { int i,N,L; cin >> N >> L; string str[110]; string concat = ""; for(i = 0; i < N ; i++) { cin >> str[i]; } sort(str,str+N); for(i = 0; i < N; i++) { concat += str[i]; } cout << concat << endl; return 0; }
AtCoderに登録したら解くべき精選過去問10問の類題をC++で解いてみた(その4)
続き。ABC 087 B - Coinsの類題です。
- 複数あ座標を線分で結んだ時にその線分の距離が最大になる距離を求める
- 距離の公式を使う。
- かつ全ての線分を探索するため2重forループを使用。
#include <iostream> #include <cmath> using namespace std; int main() { int N,x[110],y[110],i,j,k; double maxdistance = 0; double xd,yd,distance; cin >> N; for(i = 0; i < N; i++) { cin >> x[i] >> y[i]; } for(j = 0;j < N;j++) { for(k = j; k < N; k++) { xd = pow(x[j] - x[k],2.0); yd = pow(y[j] - y[k],2.0); distance = sqrt(xd + yd); if(maxdistance <= distance) { maxdistance = distance; } } } cout << maxdistance << endl; return 0; }
- 指定された文字列が全て異なる文字で形成されているかどうかを判別
- 制約上全探索しても問題ないので単純にforループを回して同じ文字があるかどうかを判定
#include <iostream> #include <string> using namespace std; int main() { int i,j; string str; cin >> str; for(i = 0; i<str.length(); i++){ for(j = i + 1; j < str.length(); j++){ if(str[i] == str[j]){ cout << "no" << endl; return 0; } } } cout << "yes" << endl; return 0; }
ABC 051 B - Sum of Three Integers
- ある数値の範囲内におさまるx,y,zがある
- x + y + z = Sとなるx,y,zの組み合わせの数を算出する
- x,y,zを全てループで回してもよいが、時間的制約も気になるので、以下のようにプログラムを組んでみた
- x,yの値はforループ
- zの値はSからxとyを引いた値とする
- このzが決められた数値の範囲内でかつ0以上かどうかを判定
#include <iostream> using namespace std; int main() { int k,s,x,y,z; int counter = 0; cin >> k >> s; for(x = 0; x <= k;x++) { for(y = 0;y <= k; y++){ z = s - x - y; if(z >= 0 && z <= k) { counter++; } } } cout << counter << endl; return 0; }