procon2019
このアカウントは京大マイコンクラブ(KMC)の2019年度の競技プログラミング練習会Normal(初心者向け)での説明用に作成したスライドです。 閲覧・参照はご自由にどうぞ。
第1回 プログラミング基礎(続),計算量, 貪欲法
担当:laft
KMC-ID:laft
あくまで一例ですが、下を参考に
型の名前 | 型の性質 | 型の値の幅(目安) |
---|---|---|
int | 32bit整数 | |
long long | 64bit整数 | |
unsigned long long | 符号なし64bit整数 | |
double | 64bit実数 | 後述 |
bool | 2値論理 | false(0),true(1) |
//int main(){
cout << fixed << setprecision(10);
精度:int < long long < double
#include<bits/stdc++.h>
using namespace std;
int main(){
int a,b;
cin >> a >> b;
//long long l = a + b;では正常に計算できないかも
long long l = (long long)a + b;
//double d = a / b;では小数部分が切り捨てられる
double d = (double)a / b;
cout << l << " " << d << endl;
}
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<int> vec(10); //次やります
for(int i=0;i<(int)vec.size();++i){ //キャスト!!!!!!
cin >> vec.at(i); //次やります
}
}
vector<int> vec; //通常の宣言。サイズ0の配列
vector<int> vec2(5); //サイズ5の配列を宣言
vector<int> vec3(5,0); //サイズ5で中身が全て0の配列を宣言
vector<int> vec(5); //宣言
for(int i=0;i<5;++i){ //入力
cin >> vec.at(i);
}
vec.at(3) = vec.at(0)+vec.at(1); //3番目の値に0番目と1番目の値の和を入れる
for(int i=0;i<5;++i){
cout << vec.at(i) << endl; //vecの中身を出力する。
}
vector<int> vec(5); //宣言
cin >> vec.at(11); //エラー
cin >> vec.at(5); //エラー
cin >> vec.at(4); //OK
#include<bits/stdc++.h>
using namespace std;
int main(){
int n; //人数
cin >> n; //人数nの入力
vector<int> a(n); //テストの得点の配列a
for(int i=0;i<n;++i){ //入力
cin >> a.at(i);
}
int ans = 0; //求める合計点
for(int i=0;i<n;++i){
ans += a.at(i); //テストの得点を全て合計点に足し合わせる。
}
cout << ans << endl; //答えの出力
}
vector<int> vec(5); //長さ5で宣言
for(int i=0;i<5;++i){ //これにより、vecの各要素に入力。
cin >> vec.at(i);
} //以下0-indexedで番目を表記
int x = 3;
vec.push_back(x); //5番目の要素にx=3を追加
vec.pop_back(); //末尾の要素を削除
vector<int> vec; //サイズ0で宣言
cout << vec.size() << endl; //この段階ではサイズ0
for(int i=0;i<10;++i){ //10回末尾に値を付け足す。
int tmp; //入力用変数
cin >> tmp; //入力
vec.push_back(tmp); //push_backで入力したものを付け足す。
}
cout << vec.size() << endl; //サイズ、つまり10を出力。
vector<int> vec = {500,100,50,10,5,1}; //初期化
vec = {1,2}; //代入
vector<int> vec = {0,1,2,3,4};
//vec.at(0) = 1;
vec[0] = 1; //内容はatと全く同じ
cout << vec[3] << endl; //入出力もできる。
cout << vec[5] << endl; //配列外だが、ただ未知の値が出力されるだけ
vector<vector<int>> vec; //宣言
vector<vector<int>> vec2(5); //サイズの初期化(縦のみ)
vector<vector<int>> vec3(5,vector<int>(5)) //サイズの初期化(縦横)
vector<vector<int>> vec4(5,vector<int>(5,0)) //サイズ、中身の初期化
vvec.at(0)
vvec.at(1)
vvec.at(2)
vector<vector<int>> vvec
表
2次元vectorの入力を受け取る方法。
#include<bits/stdc++.h>
using namespace std;
int main(){
//5x10で中身が全て0の2次元配列を宣言。
vector<vector<int>> table(5,vector<int>(10,0));
//2重ループで入力を受け取る。
for(int i=0;i<(int)table.size();++i){
for(int j=0;j<(int)table.at(i).size();++j){
cin >> table.at(i).at(j);
}
}
}
char c1,c2; //宣言
cin >> c1; //入力
c2 = 'a'; //代入
cout << c1 << " " << c2 << endl; //出力
char c1,c2; //宣言
cin >> c1; //入力
c2 = 'a'; //代入
cout << c1 << c2 << endl; //出力
char c = 'd';
c += 'A'-'a'; //大文字になる
cout << c << endl; //つまり'D'を出力
c += 'a'-'A'; //小文字になる
cout << c << endl; //つまり'd'を出力
string str1,str2; //宣言
cin >> str1; //文字列の入力
str2 = "hello"; //文字列の代入
cout << str1 << endl; //文字列の出力
string str; //宣言
str = "hello"; //文字列の代入
cout << str << endl; //文字列の出力
cout << str.size() << endl; //文字列の長さを出力。今回は5。
string str; //宣言
char c; //宣言
str = "hello"; //代入
c = str.at(0); //c='h';と等価
str.at(1) = c; //str=="hhllo"に
str.at(2) = 'h'; //str.at(2)はchar型なので代入は''
cout << c << endl; //'h'を出力
cout << str << endl; //"hhhlo"を出力
string str1,str2;
str1 = "Hello,";
str2 = "world!";
string str3 = str1+str2; //"Hello,world!"になる
//str1 = str1+str2と同じ
str1 += str2; //"Hello,world!"になる
int a,b;
cin >> a >> b;
//min()は2値を比較して小さい方を返す。
int c = min(a,b);
int a,b;
cin >> a >> b;
//min()は2値を比較して小さい方を返す関数。
int c = min(a,b);
int a,b;
cin >> a >> b;
//min()は2値を比較して小さい方を返す関数。
cout << min(a,b) << endl;
//max()は2値を比較して大きい方を返す関数。
cout << max(a,b) << endl;
int a;
long long b;
cin >> a >> b;
//min()は2値を比較して小さい方を返す関数。
//cout << min(a,b) << endl;これはエラー
//以下のように、型を揃えてあげよう。
cout << min((long long)a,b) << endl;
int a,b,c,d;
cin >> a >> b >> c >> d;
//min()は{}内の最小を返す関数でもある。
//cout << min(a,b,c,d) << endl;これはエラー
//以下のように、さらに{}で閉じよう。
cout << min({a,b,c,d}) << endl;
cout << max({a,b,c,d}) << endl;
//要素nの配列の最小値を出力する。
int n;
cin >> n;
vector<int> vec(n);
for(int i=0;i<n;++i){ //入力
cin >> vec.at(i);
}
int res = vec.at(0); //初期値
for(int i=1;i<n;++i){ //計算
res = min(res,vec.at(i));
}
cout << res << endl;
vector<int> vec = {3,1,4,5,9,2};
sort(vec.begin(),vec.end()); //低い順に並べなおす。
//{1,2,3,4,5,9}になる。
reverse(vec.begin(),vec.end()); //順番を逆にする。
//{9,5,4,3,2,1}になる。
string str = "Hello,world!";
//小文字を数える。
int low = 0;
for(int i=0;i<(int)str.size();++i){
if(islower(str.at(i))) ++low;
} //low=9
//全て大文字にする。
for(int i=0;i<(int)str.size();++i){
str[i] = toupper(str.at(i));
} //str="HELLO,WORLD!"
/*
[返り値の型] [関数名]([引数1の型] [引数名1],[引数2の型] [引数名2],..){
[処理内容]
}
*/
int min(int a,int b){
if(a < b){
return a;
}else{
return b;
}
}
//この関数では元の引数の値は書き換えられない。
//引数がコピーされてaに渡されている。
int get_minor(int a){
a *= -1; //勿論コピーされたaの計算は可能
return a;
}
//この関数で引数の値を書き換えられる。
int change_minor(int &a){
a *= -1; //元のaも-1倍される。
return a;
}
#include "bits/stdc++.h"
using namespace std;
//int型のmin関数と同等なint_min関数
int int_min(int a,int b){
if(a < b){
return a;
}else{
return b;
}
}
int main(){
int a,b;
cin >> a >> b;
//a,bの小さい方を出力
cout << int_min(a,b) << endl;
}
#include <bits/stdc++.h>
using namespace std;
//"Hello!"を出力する関数
void hello(){
cout << "Hello!" << endl;
return; //あってもなくても良い
}
int main(){
//画面に"Hello!"を出力
hello();
}
#include <bits/stdc++.h>
using namespace std;
//x回"Hello!"を出力する関数
void hello(int x){
if(x<=0) return;
cout << "Hello!" << endl;
hello(x-1);
}
int main(){
//画面に10回"Hello!"を出力
hello(10);
}
#include "bits/stdc++.h"
using namespace std;
int main(){
cout << "Hello, world!" << endl;
return 0; //書いてもOK!
}
//#include <iostream>としても良いが、
//以下のようにすると色々気にせずに済んで楽
#include<bits/stdc++.h>
using namespace std;
int main(){
cout << "Hello, world!" << endl;
}
#include<bits/stdc++.h>
//using namespace std;をつけないと、以下のように書く羽目に
int main(){
int a,b;
std::cin >> a >> b;
std::cout << std::min(a,b) << std::endl;
}
コンピューター上でプログラムを実行するのに必要な資源
Q:計算量の見積りは立てられるけれど、実際どれくらいから厳しいの?
A:以下を参考にしよう。
間に合う | |
おそらく間に合う | |
少し厳しい |
参考:蟻本p.20
整数Nが与えられる。
1からNまでの総和を計算しなさい。
問題文
制約
実行時間制限2sec
入力例
3 |
出力例
6 |
#include<bits/stdc++.h>
using namespace std;
int main(){
int N;
cin >> N;
long long ans = 0;
for(int i=1;i<=N;++i){
ans += i;
}
cout << ans << endl;
}
等差数列の和の公式って知ってますか?
例えば1からnまで順に足し合わせるとき、
1 | 2 | 3 | 4 | .... | n-3 | n-2 | n-1 | n |
n | n-1 | n-2 | n-3 | ... | 4 | 3 | 2 | 1 |
n+1 | n+1 | n+1 | n+1 | ... | n+1 | n+1 | n+1 | n+1 |
---|
合計
逆
元
#include<bits/stdc++.h>
using namespace std;
int main(){
int N;
cin >> N;
long long ans = N*(N+1)/2;
cout << ans << endl;
}
#include<bits/stdc++.h>
using namespace std;
int main(){ //これは常に3つ最も大きいものを持っておくコード
int mx1=0, mx2=0, mx3=0; //それぞれ左から最も大きいものを順に入れる。
for(int i=0;i<10;++i){
int a;
cin >> a;
if(a>mx1){ //今持ってる3つよりも大きい時、ずらして更新する
mx3 = mx2;
mx2 = mx1;
mx1 = a;
}else if(a>mx2){ //二番目よりも大きい時、ずらして2つ更新
mx3 = mx2;
mx2 = a;
}else if(a>mx3){ //三番目よりも大きい時、それだけを更新
mx3 = a;
}
}
cout << mx1+mx2+mx3 << endl; //答えを出力
}
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<int> a(10); //カードに書かれた番号を持つ配列
for(int i=0;i<10;++i){
cin >> a.at(i); //入力
}
sort(a.begin(),a.end()); //小さい順にソート
cout << a.at(7)+a.at(8)+a.at(9) << endl; //答えを出力
}
By procon2019
発表日時 2019年4月12日(金) 18:30-21:00