結果
| 問題 |
No.281 門松と魔法(1)
|
| コンテスト | |
| ユーザー |
asugen0402
|
| 提出日時 | 2019-02-07 13:52:59 |
| 言語 | C (gcc 13.3.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,254 bytes |
| コンパイル時間 | 435 ms |
| コンパイル使用メモリ | 32,128 KB |
| 実行使用メモリ | 10,624 KB |
| 最終ジャッジ日時 | 2024-06-24 20:12:14 |
| 合計ジャッジ時間 | 3,848 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 35 WA * 7 RE * 1 TLE * 1 -- * 13 |
ソースコード
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
// 内部変数
static FILE *szpFpI; // 入力
static int siDel; // 減少値
// 内部変数 - テスト用
#ifdef D_TEST
static int siRes;
static FILE *szpFpA;
#endif
// 数値 - 入れ替え
int
fSwap(
int *pipVal1 // <IO> 値1
, int *pipVal2 // <IO> 値2
)
{
int liWork = *pipVal1;
*pipVal1 = *pipVal2;
*pipVal2 = liWork;
return 0;
}
// 高さ - 減少
int
fDel(
int *pipVal // <O> 値
, int piCnt // <I> 回数
)
{
// 値 - チェック
if (*pipVal == 0) {
return -1;
}
// 値 - 減少
*pipVal -= siDel * piCnt;
if (*pipVal < 0) {
*pipVal = 0;
}
return piCnt;
}
// 回数 - 取得
int
fGetCnt(
int *pipBM // <IO> 真ん中の竹
, int *pipBL // <IO> 片側(大)
, int *pipBS // <IO> 片側(小)
)
{
int liDCnt;
// 3本同一
if (*pipBM == *pipBL && *pipBL == *pipBS) {
liDCnt = fDel(pipBS, 1);
if (liDCnt < 0) {
return -1;
}
// 再帰
return liDCnt + fGetCnt(pipBM, pipBL, pipBS);
}
// 2本同一 - 真ん中と片側(小)
if (*pipBM == *pipBS) {
liDCnt = fDel(pipBM, 1);
if (liDCnt < 0) {
return -1;
}
// 再帰
return liDCnt + fGetCnt(pipBM, pipBL, pipBS);
}
// 2本同一 - 真ん中と片側(大) or 片側(大)と片側(小)
if (*pipBM == *pipBL || *pipBL == *pipBS) {
liDCnt = fDel(pipBL, 1);
if (liDCnt < 0) {
return -1;
}
if (*pipBL < *pipBS) {
fSwap(pipBL, pipBS);
}
// 再帰
return liDCnt + fGetCnt(pipBM, pipBL, pipBS);
}
// 片側(大) > 真ん中 > 片側(小)
if (*pipBL > *pipBM && *pipBM > *pipBS) {
// 真ん中を最大化
int liBM1 = *pipBM;
int liBL1 = *pipBL;
int liBS1 = *pipBS;
int liCnt1 = (liBL1 - liBM1) / siDel + 1;
liDCnt = fDel(&liBL1, liCnt1);
if (liDCnt < 0) {
liDCnt = INT_MAX;
}
else {
liCnt1 = liDCnt + fGetCnt(&liBM1, &liBL1, &liBS1);
}
// 真ん中を最小化
int liBM2 = *pipBM;
int liBL2 = *pipBL;
int liBS2 = *pipBS;
int liCnt2 = (liBM2 - liBS2) / siDel + 1;
liDCnt = fDel(&liBM2, liCnt2);
if (liDCnt < 0) {
liDCnt = INT_MAX;
}
else {
liCnt2 = liDCnt + fGetCnt(&liBM2, &liBL2, &liBS2);
}
// 少ない回数を適用
if (liCnt1 < liCnt2) {
*pipBM = liBM1;
*pipBL = liBL1;
*pipBS = liBS1;
liDCnt = liCnt1;
}
else if (liCnt1 == INT_MAX) {
return -1;
}
else {
*pipBM = liBM2;
*pipBL = liBL2;
*pipBS = liBS2;
liDCnt = liCnt2;
}
// 再帰
return liDCnt + fGetCnt(pipBM, pipBL, pipBS);
}
return 0;
}
// 実行メイン
int
fMain(
int piTNo // <I> テスト番号 1~
)
{
char lc1Buf[1024], lc1Out[1024];
// 入力 - セット
#ifdef D_TEST
sprintf(lc1Buf, ".\\Test\\T%d.txt", piTNo);
szpFpI = fopen(lc1Buf, "r");
sprintf(lc1Buf, ".\\Test\\A%d.txt", piTNo);
szpFpA = fopen(lc1Buf, "r");
siRes = 0;
#else
szpFpI = stdin;
#endif
// 減少値 - 取得
fgets(lc1Buf, sizeof(lc1Buf), szpFpI);
sscanf(lc1Buf, "%d", &siDel);
// 片側の竹(大) - 取得
int liBL;
fgets(lc1Buf, sizeof(lc1Buf), szpFpI);
sscanf(lc1Buf, "%d", &liBL);
// 真ん中の竹 - 取得
int liBM;
fgets(lc1Buf, sizeof(lc1Buf), szpFpI);
sscanf(lc1Buf, "%d", &liBM);
// 片側の竹(小) - 取得
int liBS;
fgets(lc1Buf, sizeof(lc1Buf), szpFpI);
sscanf(lc1Buf, "%d", &liBS);
if (liBL < liBS) {
fSwap(&liBL, &liBS);
}
// 回数 - 取得
int liCnt = fGetCnt(&liBM, &liBL, &liBS);
// 結果 - セット
sprintf(lc1Out, "%d\n", liCnt);
// 結果 - 表示
#ifdef D_TEST
fgets(lc1Buf, sizeof(lc1Buf), szpFpA);
if (strcmp(lc1Buf, lc1Out)) {
siRes = -1;
}
#else
printf("%s", lc1Out);
#endif
// 残データ有無
#ifdef D_TEST
lc1Buf[0] = '\0';
fgets(lc1Buf, sizeof(lc1Buf), szpFpA);
if (strcmp(lc1Buf, "")) {
siRes = -1;
}
#endif
// テストファイルクローズ
#ifdef D_TEST
fclose(szpFpI);
fclose(szpFpA);
#endif
// テスト結果
#ifdef D_TEST
if (siRes == 0) {
printf("OK %d\n", piTNo);
}
else {
printf("NG %d\n", piTNo);
}
#endif
return 0;
}
int
main()
{
#ifdef D_TEST
int i;
for (i = D_TEST_SNO; i <= D_TEST_ENO; i++) {
fMain(i);
}
#else
fMain(0);
#endif
return 0;
}
asugen0402