競技プログラミング関連の記事は初めてなので,お手柔らかにお願いします.
#競技プログラミングにおける入出力
さて,競技プログラミングをやっている方で,入出力で苦労された方はいらっしゃいますでしょうか?
私は苦労しました.
「整数Nが与えられ,整数Nを出力しなさい」
というタイプの問題の場合,LeetCode等では入出力を
int function(int N){
return N;
}
と関数の引数と返り値で指定するのに対し,AtCoder等では
#include <bits/stdc++.h>
using namespace std;
int main(){
int N;
cin >> N;
cout << N;
return 0;
}
と標準入出力を用いる必要があります.
しかし,この方法では,入力がa, b, c, dと4つもある時は
cin>>a>>b>>c>>d;
となり,">"の数を間違えたり,1行が長く見辛い,といった問題が生じます.
これを
IN(a,b,c,d);
と指定できるようにしましょう,というのがこの記事の目的です.
#可変長テンプレート
Cっぽくマクロを使おうとしても,マクロの展開が一回しかできないため,再帰的な定義ができません,
そこで,C++11から使える可変長テンプレートを使います.
inline void IN(void){
return;
}
template <typename First, typename... Rest>
void IN(First& first, Rest&... rest){
cin >> first;
IN(rest...);
return;
}
このようにすると目的を達成できます.
出力についても同様に,
inline void OUT(void){
cout << "\n";
return;
}
template <typename First, typename... Rest>
void OUT(First first, Rest... rest){
cout << first << " ";
OUT(rest...);
return;
}
とすれば綺麗になります.
#例
4つの入力a,b,c,dがある時に,逆順d,c,b,aで出力する.
#include<bits/stdc++.h>
using namespace std;
inline void IN(void){
return;
}
template <typename First, typename... Rest>
void IN(First& first, Rest&... rest){
cin >> first;
IN(rest...);
return;
}
inline void OUT(void){
cout << "\n";
return;
}
template <typename First, typename... Rest>
void OUT(First first, Rest... rest){
cout << first << " ";
OUT(rest...);
return;
}
int main(){
int a,b,c,d;
IN(a,b,c,d);
OUT(d,c,b,a);
return 0;
}
#注意事項
このままだと,OUTを用いる時に,出力に余分な空白が生じてしまいます.
これを防ぐには,
inline void OUT(void){
cout << "\b\n";
return;
}
と"\b"を入れてあげれば解決します.
が,"\b"を入れるとAtCoderでは何故かWAになってしまいますので注意してください.
#参考サイト
http://yohshiy.blog.fc2.com/blog-entry-300.html
https://cpprefjp.github.io/lang/cpp11/variadic_templates.html