AtCoder Beginners SelectionをC言語で解く

AtCoderで常設で開催されているコンテスト
**AtCoder Beginners Selection**
をC言語で解いてみました。

:::note info
自分が提出したコードをほぼそのまま載せていますので、まだまだ改良点はあるかとは思います。
:::
:::note info
コードの書き方に統一性がないことがありますが、ご容赦ください。
:::

# [PracticeA：Welcome to AtCoder](https://atcoder.jp/contests/abs/tasks/practice_1)
この問題は解説する必要がないと思いますので、コードのみ記載します。
```c
#include <stdio.h>
int main(void) {
	int a, b, c;
	char s[110];
	scanf("%d%d%d", &a, &b, &c);
	scanf("%s", s);
	printf("%d %s\n", a + b + c, s);
	return 0;
}
```

# [ABC086A：Product](https://atcoder.jp/contests/abs/tasks/abc086_a)
3項演算子を使ってみました。
```c
#include <stdio.h>
int main(void) {
	int a, b;
	scanf("%d%d", &a, &b);
	printf((a * b) % 2 == 0 ? "Even\n" : "Odd\n");
	return 0;
}
```

# [ABC081A：Placing Marbles](https://atcoder.jp/contests/abs/tasks/abc081_a)
入力は最大でも3桁しかなく、
各桁は1 or 0のみ入力となるので、
各桁の数を求め、その合計が答えとなります。
 ```c
#include <stdio.h>
int main(void) {
	int s;
	scanf("%d", &s);
	printf("%d\n",s%10+(s/10)%10+(s/100)%10);
	return 0;
}
```

# [ABC081B：Shift only](https://atcoder.jp/contests/abs/tasks/abc081_b9)
入力された数字を全て調べて2で割り切れない数があった場合はループを抜け、
そうでない場合、2で割った値で更新、
全て割り切れた場合はインクリメントをし、
ループ抜けるまで繰り返します。
インクリメントした値が答えとなります。

:::note warn
見直してみると最後の方の **if(flag==0)** は不要ですね。
:::

```c
#include <stdio.h>
int main(void) {
	int n;
	scanf("%d", &n);
	int i, j;
	int a[210];
	for (i = 0; i < n; i++) {
		scanf("%d", &a[i]);
	}
	int flag = 0;
	int count = 0;
	while (flag == 0) {
		for (i = 0; i < n; i++) {
			if (a[i] % 2 != 0) {
				flag = 1;
				break;
			}
			else {
				a[i] /= 2;
			}
		}
		if(flag==0) count++;
	}
	printf("%d\n", count);
	return 0;
}
```

# [ABC087B：Coins](https://atcoder.jp/contests/abs/tasks/abc087_b)
計算時間を短くするために、
合計金額が**x円**を<font color="Red">**超えた場合**</font>と<font color="Blue">**一致した場合**</font>は**continue**で一部スキップしています。
```c
#include <stdio.h>
int main(void) {
	int a, b, c;
	int x;
	int count = 0;
	int i, j, k;

	scanf("%d%d%d", &a, &b, &c);
	scanf("%d", &x);
 
	for (i = 0; i <= a; i++) {
		int sum1 = i * 500;
		if (sum1 > x) continue;
		if (sum1 == x) {
			count++;
			continue;
		}
		for (j = 0; j <= b; j++) {
			int sum2 = j * 100;
			if (sum1 + sum2 > x) continue;
			if (sum1 + sum2 == x) {
				count++;
				continue;
			}
			for (k = 0; k <= c; k++) {
				int sum3 = k * 50;
				if (sum1 + sum2 + sum3 > x) continue;
				if (sum1 + sum2 + sum3 == x) {
					count++;
					continue;
				}
			}
		}
	}
	printf("%d\n", count);
	return 0;
}
```

# [ABC083B：Some Sums](https://atcoder.jp/contests/abs/tasks/abc083_b)
wa関数を作り、この関数で引数の数字の各桁の和を求めています。
和が範囲内の場合に引数の数字を足すといったことを行っています。

```c
#include <stdio.h>
int wa(int n);
int main(void) {
	int n,a, b;
	int count = 0;
	int i;

	scanf("%d%d%d", &n,&a, &b);
	for (i = 1; i <= n; i++) {
		int sum = wa(i);
		if (a <= sum && sum <= b) count+=i;
	}
	printf("%d\n", count);
	return 0;
}
 
int wa(int n) {
	int sum=0;
	while (n != 0) {
		sum += n % 10;
		n /= 10;
	}
	return sum;
}
```

# [ABC088B：Card Game for Two](https://atcoder.jp/contests/abs/tasks/abc088_b)
降順でソートし、
奇数番目(配列の添え字では偶数)のときは足し算
偶数番目(配列の添え字では奇数)のときは引き算
をしたものが答えとなります。
ソートにはqsort関数を使用しました。
```c
#include <stdio.h>
#include <stdlib.h>
int sort(const void* a, const void* b);
int main(void) {
	int n, a[110] = { 0 };
 
 
	int count = 0;
	int i;
	scanf("%d", &n);
	for (i = 0; i < n; i++) {
		scanf("%d", &a[i]);
	}
	qsort(a, sizeof(a) / sizeof(int), sizeof(int), sort);
	for (i = 0; i < n; i++) {
		if ((i % 2) == 0)  count += a[i];
		else count -= a[i];
	}
	printf("%d\n", count);
	return 0;
}
 
int sort(const void* a, const void* b) {
	return *(int*)b - *(int*)a;
}
```

# [ABC085C：Otoshidama](https://atcoder.jp/contests/abs/tasks/abc085_c)
解説とか見たら2重ループで解けることが分かったのですが、
そこまでの頭がなく、3重ループになってしまいました。
goto文使いたくなかったので、フラグを立ててループを抜けています。
計算時間短くするために合計枚数がNを超えた時点でループ抜けています。
```c
#include <stdio.h>
int main(void) {
	long long n, y;
	long long i, j, k;
	int flag = 0;
	scanf("%lld%lld", &n, &y);
 
	for (i = 0; i <= n; i++) {
		for (j = 0; j <= n; j++) {
			if (i + j > n) break;
			for (k = 0; k <= n; k++) {
				if (i + j + k > n)break;
				if ((i * 10000 + j * 5000 + k * 1000) == y&&i+j+k==n) {
					flag = 1;
					break;
				}
			}
			if (flag == 1) break;
		}
		if (flag == 1) break;
	}
 
	if (flag == 0) printf("-1 -1 -1\n");
	else printf("%lld %lld %lld\n", i, j, k);
	return 0;
}
```

# [ABC049C：白昼夢](https://atcoder.jp/contests/abs/tasks/arc065_a)
私にとってはかなりの難問で、自力では解けませんでした。
ネット上の解説に書かれていた文字を反転させると文字被りがなくなる
というのを見て解くことができました。
まず入力された文字列を逆順にし、
**check_st関数**にてあっているかの判別をしています。
**check_st関数**では、文字が**NULL文字**になるまでループし、
4種の文字のいずれかに該当したら該当文字数分**文字をずらして**( *ポインターでインクリメントをすることでずらしています* )
最終的にNULL文字になったときはYES、途中で4種の文字のいずれにも該当しない場合はNOとして判定を行っています。
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int check_st(char* s);
const char* st[] = { "maerd","remaerd","esare","resare" };
int main(void) {
	char s[100010] = { 0 };
 
	scanf("%s", s);
	for (int i = 0; i < (strlen(s)) / 2; i++) {
		char tmp;
		tmp = s[i];
		s[i] = s[strlen(s) - 1 - i];
		s[strlen(s) - 1 - i] = tmp;
	}
 
	
	printf(check_st(s)==0?"YES\n":"NO\n");
	return 0;
}
 
int check_st(char* s) {
	int flag;
	while (s[0] != '\0') {
		flag = 0;
		for (int i = 0; i < 4; i++) {
			if (strncmp(s, st[i], strlen(st[i])) == 0) {
				for (int j = 0; j < strlen(st[i]); j++) {
					s++;
				}
				flag = 1;
				break;
			
			}
			if (s[0] == '\0') break;
		}
		if (flag == 0) return 1;
	}
	return 0;
}
```

# [ABC086C：Traveling](https://atcoder.jp/contests/abs/tasks/arc089_a)
この問題も自力では解けませんでした。
ネットで[解説しているサイト](https://cloraordinary.com/atcoderabc086c-traveling-ruby)(言語はRuby)があったので、
そのアルゴリズムを参照して書きました。
このアルゴリズムは非常に参考になりました。

```c
#include <stdio.h>
#include <stdlib.h>
int travel(int t1, int x1, int y1, int t2, int x2, int y2) {
	int mv = 0;
	mv = (t2 - t1) - abs((x1 + y1) - (x2 + y2));
	if (mv < 0) {
		return 1;
	}
	else if (mv % 2 == 0) {
		return 0;
	}
	else {
		return 1;
	}

}

int main(void)
{
	int n;
	int t[100010] = { 0 }, x[100010] = { 0 }, y[100010] = { 0 };

	scanf("%d", &n);

	for (int i = 0; i < n; i++) {
		scanf("%d%d%d", &t[i + 1], &x[i + 1], &y[i + 1]);
	}
	int flag = 0;
	for (int i = 0; i < n; i++) {
		flag = travel(t[i], x[i], y[i], t[i + 1], x[i + 1], y[i + 1]);
		if (flag == 1) break;
	}

	printf("%s\n", flag == 0 ? "Yes" : "No");

	return 0;
}
```