課題 1.6 2013年度パソコン甲子園予算問題3
(2014.9.28の朝の実習問題. みんなが納得できるプログラムが完成したのは、午後でした。。)

<問題>

<入力>

<出力>

<入出力例>

入力例1

入力例2

入力例3

5

1 2 3 6 4 5

6

1 3 6 9 12 15 18

4

5 7 9 11 12

出力例1

出力例2

出力例3

6

1

12



解答例 (制限時間は60分) 

方法1:一本ずつ先頭に移動し、残りが正しいか確認。 
#include <stdio.h> 

int main (void) { 
   int i, j, n, nae[100], t; 
   scanf("%d", &n); 
   /* 苗を格納 5本以上と仮定 */
   for (i = 0; i <= n; i++) 
      scanf("%d", &nae[i]); 

   /* 1本ずつ、先頭へ移動して、残りをチェック */ 
   /* 先頭は、1つ前の動かしたものでもある */ 
   for (i = 0; i <= n; i++) { 
      t = nae[0]; /* i番目の苗をその時点の先頭と交換 */ 
      nae[0] = nae[i]; 
      nae[i] = t; 
 
      /* 先頭以降におかしいところがあれば、break */ 
      for (j=1; j < n-1; j++) { 
         if (nae[j+1] - nae[j] != nae[j+2] - nae[j+1]) 
            break; 
      } 

      /* おかしなところがなかった場合 先頭にあるものがおかしい */ 
      if (j == n-1) { 
         printf("%d\n", nae[0]); 
         break; 
      } 
   }
 
   return 0; 
} 

方法2:正しいか(a[0]-a[1])確認。あとはおかしいところを探す。 
#include <stdio.h> 

int main (void) { 
   int n, i, diff; 
   int a[100]; 

   scanf("%d", &n); 
   for (i=0; i <= n; i++) 
      scanf ("%d", &a[i]); 

   /* 0個目が雑草 残り全て正しい */ 
   for (i = 2; i < n; i++) { 
      if (a[i+1] - a[i] != a[2] - a[1]) 
         break; 
   } 

   if (i == n) { 
      printf ("%d\n", a[0]); 
      return 0; 
   } 

   /* 1個目が雑草 そこを抜けば、全て正しい */ 
   for (i = 2; i < n; i++) { 
      if (a[i+1] - a[i] != a[2] - a[0]) 
         break; 
   } 

   if (i == n) { 
      printf ("%d\n", a[1]); 
      return 0; 
   } 
 
   /* a[0]とa[1]は正しい おかしいところを見つける */ 
   diff = a[1] - a[0]; 
   for (i=2; i <= n+1; i++) { 
      if (a[i] != a[0] + diff*i) { 
         printf("%d\n", a[i]); 
         break; 
      } 
   } 

   return 0; 
}