백준: Silver② - 1292, 1312, 1316, 1331
</br>
계속 풀이
</br>
1292: 쉽게 푸는 문제
https://www.acmicpc.net/problem/1292
1 2 2 3 3 3 4 4 4 4 … 같은 수열에서 구간의 합 구하기
방법 1.
int ia = 0, ib;
for(int i = 1; i < 1000; i++){
if( ia == 0 && i*(i+1)/2 >= a ){
ia = i;
}
if( i*(i+1)/2 >= b ){
ib = i;
break;
}
}
int ans = 0;
if( ia == ib ){
if( a == b ) ans = ia;
else ans += (b-a+1) * ia;
cout << ans << endl;
return 0;
}
ans += ( b - ib*(ib-1)/2 ) * ib;
ans += ( ia*(ia+1)/2 - a + 1 ) * ia;
for(int i = ia+1; i < ib; i++){
ans += i*i;
}
cout << ans << endl;
처음에 쓴 코드는 사람처럼 머리 써서 구하는 코드다.
시작점과 끝점에 해당하는 수를 각각 알아내고, 더해주는 코드…
하지만 구현도 귀찮고 복잡하니까, 컴퓨터 답게 푸는 코드를 다시 써 보았다.
방법 2.
int l = 1;
for(int i = 1; i <= b; i++){
for(int j = 0; j < l; j++){
L[i+j] = l;
}
i += l-1;
l++;
}
int ans = 0;
for(int i = a; i <= b; i++){
ans += L[i];
}
cout << ans << endl;
이건 그냥 수열을 다 구하고, 구간 합을 더해서 구한다.
범위가 1000까지기 때문에 시간도 안 걸린다.
</br>
1312: 소수
https://www.acmcpc.net/problem/1312
A를 B로 나누었을 때 소수점 N번째 숫자 구하기
int ans = 0;
for(int i = 0; i < n; i++){
a %= b;
a *= 10;
ans = a/b;
}
cout << ans << endl;
사람이 하는 나눗셈을 그대로 구현하면 된다.
A를 B로 나누고 나머지를 저장하고, 그걸 10배 해 주고, 몫을 답에 저장하고
</br>
1316: 그룹 단어 체커
https://www.acmcpc.net/problem/1316
알파벳이 연속해서 안 나오고 띄엄 띄엄 나오는 지 보기
int cnt = 0;
for(int i = 0; i < n; i++){
string s;
cin >> s;
memset(alphabets, 0, 26*sizeof(int));
s += s[s.size()-1];
cnt++;
for(int i = 0; i < s.size()-1; i++){
if( alphabets[s[i]-'a'] ){
cnt--;
break;
}
if( s[i] != s[i+1] ){
alphabets[s[i]-'a'] = 1;
}
}
}
cout << cnt << endl;
for문에서 만약 현재 문자와 다음 문자가 달라질 때 alphabets[]
에 표시해 준다. 그리고 만약 그 문자가 나중에 다시 나온다면 alphabets[]
에서 이미 체크되었으므로 cnt--
해 준다.
</br>
1331: 나이트 투어
https://www.acmicpc.net/problem/1331
나이트의 움직임으로 모든 칸을 순회할 수 있는 지 확인하기
int prevx = s[0] - 'A';
int prevy = s[1] - '1';
int startx = prevx;
int starty = prevy;
mmap[prevx][prevy] = 1;
for(int i = 1; i < 36; i++){
cin >> s;
int x = s[0] - 'A';
int y = s[1] - '1';
bool b = false;
for(int j = 0; j < 8; j++){
if( prevx + movex[j] == x && prevy + movey[j] == y ){
b = true;
break;
}
}
if( !b ){
cout << "Invalid" << endl;
return 0;
}
if( mmap[x][y] ){
cout << "Invalid" << endl;
return 0;
}
mmap[x][y] = 1;
prevx = x, prevy = y;
}
bool b = false;
for(int j = 0; j < 8; j++){
if( prevx + movex[j] == startx && prevy + movey[j] == starty ){
b = true;
break;
}
}
if( !b ){
cout << "Invalid" << endl;
return 0;
}
cout << "Valid" << endl;
그냥… 했다 시키는 대로
나이트의 움직임이 맞는 지 확인하고, 이미 방문했는 지도 확인하고, 가장 마지막 방문점이 시작점인 지도 확인한다.
</br>
열심히 하자
</br>
댓글남기기