結果

問題 No.45 回転寿司
ユーザー arishikiarishiki
提出日時 2016-04-05 16:30:27
言語 C90
(gcc 11.4.0)
結果
WA  
実行時間 -
コード長 2,359 bytes
コンパイル時間 163 ms
コンパイル使用メモリ 24,160 KB
実行使用メモリ 6,824 KB
最終ジャッジ日時 2024-11-24 11:33:07
合計ジャッジ時間 1,033 ms
ジャッジサーバーID
(参考情報)
judge5 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 WA -
testcase_01 WA -
testcase_02 WA -
testcase_03 WA -
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 WA -
testcase_22 AC 1 ms
6,816 KB
testcase_23 AC 0 ms
6,816 KB
testcase_24 AC 0 ms
6,816 KB
testcase_25 AC 1 ms
6,820 KB
testcase_26 WA -
testcase_27 WA -
testcase_28 WA -
testcase_29 WA -
testcase_30 WA -
testcase_31 AC 1 ms
6,820 KB
testcase_32 AC 1 ms
6,816 KB
testcase_33 WA -
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.c: In function ‘main’:
main.c:47:3: warning: ignoring return value of ‘scanf’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
   47 |   scanf("%d", &N);
      |   ^~~~~~~~~~~~~~~
main.c:55:23: warning: ignoring return value of ‘scanf’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
   55 |   for(i=2;i<=N+1;i++) scanf("%d", V+i);
      |                       ^~~~~~~~~~~~~~~~

ソースコード

diff #

#include <stdio.h>
/* ルールの説明がわかりにくいが、
 間を1個以上開けた上昇列として指定し、
 和が最大になるようにする*/
/* 間は1個開けるか2個開けるかどっちか。
 なぜなら、3つ以上開ける時、その真ん中にあるやつを他を変えずに取れるから。*/
/* 最初の2個のうち、どちらかはとることになる*/

/* 寿司の基本定理
-*-の方が*-*より大きい
ならば真ん中は必ず採用
 */

/*

*--*-*-*-*-*-*--*
*-*-*-*-*-*-*-*-*

2空けが2回以上出てくる時、
必ずこのパターン。
 */

/*
 *-*-*--*-*-*--*
 *-*-*-*-*-*-*-*

 *--*-*-*--*
 *-*-*-*-*-*

 *--*-*--*--*
 *-*-*-*-*
 
 *--*-*--*
 *-*-*-*
 *--*--*

 *-*-*-*-*
 *--*-*--*
 */

int mymax(int a, int b);

int sum_1step(int *V, int s, int e);

int main(void){
  int i, j, j1=0, N, M, all1, two2, s1, start, end, s=0, temp=0, t=0;
  scanf("%d", &N);

  int V[N+4];
  V[0]=0;
  V[1]=0;
  V[N+2]=0;
  V[N+3]=0;
  
  for(i=2;i<=N+1;i++) scanf("%d", V+i);

  start=0;
  end=1;

  for(end=start+6;end<=N+3 && !(end==N+2);end+=2){
    for(s1=start;s1+6<=end;s1+=2){
      all1=sum_1step(V, s1+2, end-2);
      two2=sum_1step(V, s1+3, end-3);
      if(two2>all1){
	s+=sum_1step(V, start, s1-2);
	/* *-*--*-*--*
	 s1から(end-3)までの間で、間隔2を最大にするものを選ぶ*/
	M=(end-3-s1+1)/2; //Mは個数
	for(j=1;j<=M-1;j++){
	  temp=sum_1step(V, s1, s1+(j-1)*2);
	  temp+=sum_1step(V, s1+(j-1)*2+3, end-3);
	  if(t<temp){
	    j1=j;
	    t=temp;
	  }//最大値をとるjをj1に登録
	}//s1から始まってj-1個の間隔1, 次に間隔2で次のstart
	s+=sum_1step(V, s1, s1+(j1-1)*2);
	start=s1+(j1-1)*2+3;
	end=start+4;
	break;
      }
    }
  }

  end=N+3; //startは生きてる。
  if((M=end-start+1)%2==0){//この時2の間隔がちょうど一個
      for(j=1;j<=M/2-1;j++){
	temp=sum_1step(V, start, start+(j-1)*2);//jは間隔が2になる以前の個数
	temp+=sum_1step(V, start+(j-1)*2+3, end);
	t=mymax(t, temp);
      }
    s+=t;
    printf("%d\n", s);
  }
  else{ //この時あとは2の間隔なし
    s+=sum_1step(V, start, end);
    printf("%d\n", s);
  }
  return 0;
}

int mymax(int a, int b){
  if(a>b) return a;
  else return b;
}

int sum_1step(int *V, int s, int e){
  int i, sum=0;
  for(i=s;i<=e;i+=2) sum+=V[i];

  return sum;
}
0