6
2012/6/14 1 ACM-ICPC June 22, 2012 Prog 0 Special lecture m5161121 Yohei Mori, University of AIZU ACM-ICPCロゴ ACM-ICPC ACMが主催するプログラミングコンテスト。 ACM(Association for Computing Machinery) ICPC INTERNATIONAL (国際) COLLEGIATE (大学対抗) PROGRAMMING CONTEST(プログラミングコンテスト) Rule 大学内で31組のチーム。 時間内により多くの問題をプログラムを用 いて解けば勝ち。 チームで1台のコンピュータ。 並列コーディング不可。 コードを書く人、解法を考える人、など得意によっ て分担が存在するチームもある。 その他細かい規定。 問題を解くと対応した 色の風船があがる。 Roadmap 1. チーム編成 2. チーム登録 3. 国内予選 4. 突破したら、アジア地区大会(日本か遠征で アジア諸外国) 5. 地区大会も突破したら、世界大会 2008年度大会で会津大は世界大会(Stockholm) に出場している。 What is Problem Solving 問題を解く流れ。 1. 問題が何を求めているか理解する。 どんな問題か、得意そうな人がいたらそのメンバーに 相談、あるいは任せる。 2. 問題の制約(変数の条件)を理解する。 3. 適切な解法を考える。 4. プログラムで実装する。 5. ジャッジシステムにかける。 たとえばOnline Judge(後出)

ACM-ICPC - 会津大学公式ウェブサイトweb-ext.u-aizu.ac.jp/course/prog0/images/8/84/ACM-ICPC.pdf2012/6/14 2 Problem •ACM-ICPC 2011 国内予選 問題A •何個かの正の整数nに対して、nより大きく2n

  • Upload
    others

  • View
    22

  • Download
    0

Embed Size (px)

Citation preview

Page 1: ACM-ICPC - 会津大学公式ウェブサイトweb-ext.u-aizu.ac.jp/course/prog0/images/8/84/ACM-ICPC.pdf2012/6/14 2 Problem •ACM-ICPC 2011 国内予選 問題A •何個かの正の整数nに対して、nより大きく2n

2012/6/14

1

ACM-ICPC

June 22, 2012 Prog 0 Special lecture

m5161121 Yohei Mori, University of AIZU

ACM-ICPCロゴ

ACM-ICPC

• ACMが主催するプログラミングコンテスト。

– ACM(Association for Computing Machinery)

• ICPC

– INTERNATIONAL (国際)

– COLLEGIATE (大学対抗)

– PROGRAMMING

– CONTEST(プログラミングコンテスト)

Rule

• 大学内で3人1組のチーム。

• 時間内により多くの”問題”をプログラムを用いて解けば勝ち。

• チームで1台のコンピュータ。

–並列コーディング不可。

– コードを書く人、解法を考える人、など得意によって分担が存在するチームもある。

• その他細かい規定。

問題を解くと対応した色の風船があがる。

Roadmap

1. チーム編成

2. チーム登録

3. 国内予選

4. 突破したら、アジア地区大会(日本か遠征でアジア諸外国)

5. 地区大会も突破したら、世界大会

– 2008年度大会で会津大は世界大会(Stockholm)に出場している。

What is Problem Solving

• 問題を解く流れ。

1. 問題が何を求めているか理解する。

どんな問題か、得意そうな人がいたらそのメンバーに相談、あるいは任せる。

2. 問題の制約(変数の条件)を理解する。

3. 適切な解法を考える。

4. プログラムで実装する。

5. ジャッジシステムにかける。

たとえばOnline Judge(後出)。

Page 2: ACM-ICPC - 会津大学公式ウェブサイトweb-ext.u-aizu.ac.jp/course/prog0/images/8/84/ACM-ICPC.pdf2012/6/14 2 Problem •ACM-ICPC 2011 国内予選 問題A •何個かの正の整数nに対して、nより大きく2n

2012/6/14

2

Problem

• ACM-ICPC 2011 国内予選 問題A

• 何個かの正の整数nに対して、nより大きく2n以下の素数の数を求めよ。

–素数とは? • 1と自身以外の数すべてで割りきれない整数。

• n<=123,456

• nが何個かはわからない。

Solution

• 123456以下の素数をすべて求めればいい。

• ある数xが素数であるかどうか(素数判定)。

– 2以上x未満の数でxを割りきる場合xは素数ではない。

int is_x_prime = 1;

for(int i = 2; i < x; ++i){

if( x % i == 0 ) is_x_prime = 0;

}

if( is_x_prime ) printf(“%d is prime!¥n”, x);

Solution (cont.)

• 正の整数nを次々に読み取り、nより大きく2n

以下の数すべてについて素数判定し、素数だった数をカウントする。

• nが0のときプログラムを終了する。

Code

#include<stdio.h>

#include<stdlib.h>

int main(int argc, char *argv[])

{

while(1){

int i, x, n;

int res = 0;

scanf("%d", &n);

if( n == 0 ) break;

for(x = n+1; x <= 2*n; ++x){

int is_x_prime = 1;

for(i = 2; i < x; ++i){

if( x % i == 0 ){

is_x_prime = 0;

}

}

if( is_x_prime ) ++res;

}

printf("%d¥n", res);

}

return (EXIT_SUCCESS);

}

Execution Example

• n=5のときnより大きくから2n以下の数:6,7,8,9,10の中にたしかに素数7がひとつだけある。

• 実際の解答プログラムには”n = “や”Answer : “といった文字列は要らない。

Verification

• ジャッジシステムにかける。

• しかし、本番のジャッジシステムはいつでも使用できるわけではないので、Online Judgeと呼ばれるWebサービスに「投げ(Submit) 」る。

• Online Judgeは主にコンテストの過去問題を

保存し、対応する問題に対して解答プログラムを判定することができる。

Page 3: ACM-ICPC - 会津大学公式ウェブサイトweb-ext.u-aizu.ac.jp/course/prog0/images/8/84/ACM-ICPC.pdf2012/6/14 2 Problem •ACM-ICPC 2011 国内予選 問題A •何個かの正の整数nに対して、nより大きく2n

2012/6/14

3

Online Judge

• 会津大学のデータベース研究室で運用されているAizu Online Judge(AOJ)を使用。

Problem Selection

• 今の問題を探す(AOJに収録済み)。

–ちなみに国内予選7問のうち、最初の問題なので簡単な問題。

問題1172: Chebyshev’s Theorem 正答率:72.63%, 正解者:205人

Submission

• Submitボタンで投げる。

• C言語のほか、C++,C++11,C#,D,Javaも対応。

Submission

• Waiting Judge (判定待ち)

Judge Result

• Time Limit Exceeded(時間超過)

–あなたのプログラムは実行時間が長すぎます。

Time Limit ?

• 長すぎるとは?

–時間制限があり、8秒。

• 8秒以内に入力ファイルに書かれている整数nすべてに対して正しい出力をする必要。

– しかしnが一体いくつあるかは書いていない。

– n=123456(制約の上限)を入力すると…

• 1172.in に n がひとつ書かれている。

• 約6秒かかる(@2.80GHz, 1 thread)。

Page 4: ACM-ICPC - 会津大学公式ウェブサイトweb-ext.u-aizu.ac.jp/course/prog0/images/8/84/ACM-ICPC.pdf2012/6/14 2 Problem •ACM-ICPC 2011 国内予選 問題A •何個かの正の整数nに対して、nより大きく2n

2012/6/14

4

What is WORST Case?

• もしnが何百個もあり、すべて100,000程度の数だったら…?

–オンラインジャッジでは独自、あるいは大会公式の入力を用意している。

–入力は厳しい。

• ひとつひとつのnに対して高速に答えを求めなければならない。

↓たとえば

Another Solution

• 素数pの倍数Pは素数ではない –なぜならPは明らかにpで割り切れる。

• 配列isPrimeにその添え字が素数かどうかを記録する。 – isPrime[2] = 1, isPrime[3] = 1, isPrime[4] = 0,

isPrime[5] = 1 … • あるisPrime[i] = 1となるiについて、isPrime[i*j] = 0である(j>=2, i*j<=123456)。

– isPrime[x] を見れば xが素数かどうか一瞬でわかる。

Code #include<stdio.h>

#include<stdlib.h>

#define N 2*123456

int main(int argc, char *argv[])

{

int i, j;

int isPrime[1+N];

// すべての整数が素数と仮定

for(i = 2; i <= N; ++i){

isPrime[i] = 1;

}

// 素数である整数の倍数を素数でないとする

for(i = 2; i < N; ++i){

if( isPrime[i] ){

for(j = 2; i * j < N; ++j){

isPrime[i * j] = 0;

}

}

}

while(1){

int x, n;

int res = 0;

scanf("%d", &n);

if( n == 0 ) break;

for(x = n+1; x <= 2*n; ++x){

if( isPrime[ x ] ) ++res;

}

printf("%d¥n", res);

}

return (EXIT_SUCCESS);

}

Submission

• Waiting Judge (判定待ち)

Judge Result

• Wrong Answer (誤答)

–あなたのプログラムには誤りがあります。

Page 5: ACM-ICPC - 会津大学公式ウェブサイトweb-ext.u-aizu.ac.jp/course/prog0/images/8/84/ACM-ICPC.pdf2012/6/14 2 Problem •ACM-ICPC 2011 国内予選 問題A •何個かの正の整数nに対して、nより大きく2n

2012/6/14

5

What is WRONG ?!

• 何が違うか?

– もう一度コードを見直す。

Wrong Code #include<stdio.h>

#include<stdlib.h>

#define N 2*123456

int main(int argc, char *argv[])

{

int i, j;

int isPrime[1+N];

for(i = 2; i <= N; ++i){

isPrime[i] = 1;

}

for(i = 2; i < N; ++i){

if( isPrime[i] ){

for(j = 2; i * j < N; ++j){

isPrime[i * j] = 0;

}

}

}

while(1){

int x, n;

int res = 0;

scanf("%d", &n);

if( n == 0 ) break;

for(x = n+1; x <= 2*n; ++x){

if( isPrime[ x ] ) ++res;

}

printf("%d¥n", res);

}

return (EXIT_SUCCESS);

}

Debug

• isPrime[N=2*123456=246912] は 0でなければならない。

– 2*123456は明らかに素数ではないから。

– しかし (i * j < N=246912)では初期化以降0になることがない。

Corrected Code #include<stdio.h>

#include<stdlib.h>

#define N 2*123456

int main(int argc, char *argv[])

{

int i, j;

int isPrime[1+N];

for(i = 2; i <= N; ++i){

isPrime[i] = 1;

}

for(i = 2; i < N; ++i){

if( isPrime[i] ){

for(j = 2; i * j <= N; ++j){

isPrime[i * j] = 0;

}

}

}

while(1){

int x, n;

int res = 0;

scanf("%d", &n);

if( n == 0 ) break;

for(x = n+1; x <= 2*n; ++x){

if( isPrime[ x ] ) ++res;

}

printf("%d¥n", res);

}

return (EXIT_SUCCESS);

}

Submission

• Waiting Judge (判定待ち)

Judge Result

• Accepted(正答)

–あなたのプログラムが”このOnline Judge上で”正しいことを保証します。

ちなみにs1160219は学部時代のIDです。

Page 6: ACM-ICPC - 会津大学公式ウェブサイトweb-ext.u-aizu.ac.jp/course/prog0/images/8/84/ACM-ICPC.pdf2012/6/14 2 Problem •ACM-ICPC 2011 国内予選 問題A •何個かの正の整数nに対して、nより大きく2n

2012/6/14

6

Merits

• 数学的/論理的思考力・問題解決能力の向上

• 効率のよいコードを速く、正確に書く力

• チーム内での意思疎通

–あるいは競技プログラミングを趣味とする人々とのつながり。

• 就職につながるかも(スポンサー企業)

Sponsors

End

• ACM-ICPCに関して興味がわいた人

– ICPCに向けた練習を行うサークルがあります。部長(s1180008@u-aizu, Kazuki Omomo)か顧問の先生(yutaka@u-aizu, Yutaka Watanobe)にメールしてみましょう。

• Good luck & Have a fun for your ADVANCED programming.