요구능력 : 비트연산
코드설명 :
이론적으로 어려운 문제는 아닌데 Swift로는 난이도가 상당한문제이다.
이 문제는 wapas님의 IO을 줄여주는 코드가 없으면 풀 수 없는것같다.
아래 코드의 경우 Int는 그냥 readInt()로 받아주면 되지만, String의 경우에는 Byte의 합으로 출력을 해주므로 "add" -> 297 이런식으로 String -> 10진수로 변환해서 모든 값을 더한 값을 알아내야하는 노가다를 해줘야한다.
class FileIO {
@inline(__always) private var buffer: [UInt8] = Array(FileHandle.standardInput.readDataToEndOfFile()) + [0], byteIdx = 0
@inline(__always) private func readByte() -> UInt8 {
defer { byteIdx += 1 }
return buffer.withUnsafeBufferPointer { $0[byteIdx] }
}
@inline(__always) func readInt() -> Int {
var number = 0, byte = readByte(), isNegative = false
while byte == 10 || byte == 32 { byte = readByte() }
if byte == 45 { byte = readByte(); isNegative = true }
while 48...57 ~= byte { number = number * 10 + Int(byte - 48); byte = readByte() }
return number * (isNegative ? -1 : 1)
}
@inline(__always) func readStirngSum() -> Int {
var byte = readByte()
while byte == 10 || byte == 32 { byte = readByte() }
var sum = Int(byte)
while byte != 10 && byte != 32 && byte != 0 { byte = readByte(); sum += Int(byte) }
return sum - Int(byte)
}
@inline(__always) private func write(_ output: String) {
FileHandle.standardOutput.write(output.data(using: .utf8)!)
}
}
하나만 예시를 들어 설명하자면,
case 297:
|=연산의 경우에는 bit에 |=의 오른쪽에 있는 값과 or연산을 해서 bit에 집어넣는다는 의미이다.
1 << file.readInt()는 만약 입력을 3으로 받았다면 1 << 3이 될 것이고,
1비트를 3만큼 이동시킨다는 의미이다.
bit의 현재 값이 0이라면 나머지 비트는 그대로이고 3 + 1번째 비트만 1로 바뀌게 된다.
만약 00000이 있다면, 01000 이 된다.
switch file.readStirngSum(){
case 297:
bit |= (1 << file.readInt())
case 654:
bit &= ~(1 << file.readInt())
case 510:
if (bit & (1 << file.readInt()) != 0){
result.append("1\n")
}else{
result.append("0\n")
}
case 642:
bit ^= (1 << file.readInt())
case 313:
bit |= (~0)
case 559:
bit &= 0
default:
break
}
요약하자면, 비트마스킹으로 집합을 관리하였다.
1은 1번째비트 2는 2번째비트 3은 3번째비트 ... 이런식으로 관리한것이다.
만약 1번째 비트가 1이라면 1이 존재하는것이고,
1번째 비트가 0이라면 1이 존재하지 않는것이다.
후기 : 이해는 빨리했는데,, 입출력 때문에 고생한문제
import Foundation
class FileIO {
@inline(__always) private var buffer: [UInt8] = Array(FileHandle.standardInput.readDataToEndOfFile()) + [0], byteIdx = 0
@inline(__always) private func readByte() -> UInt8 {
defer { byteIdx += 1 }
return buffer.withUnsafeBufferPointer { $0[byteIdx] }
}
@inline(__always) func readInt() -> Int {
var number = 0, byte = readByte(), isNegative = false
while byte == 10 || byte == 32 { byte = readByte() }
if byte == 45 { byte = readByte(); isNegative = true }
while 48...57 ~= byte { number = number * 10 + Int(byte - 48); byte = readByte() }
return number * (isNegative ? -1 : 1)
}
@inline(__always) func readStirngSum() -> Int {
var byte = readByte()
while byte == 10 || byte == 32 { byte = readByte() }
var sum = Int(byte)
while byte != 10 && byte != 32 && byte != 0 { byte = readByte(); sum += Int(byte) }
return sum - Int(byte)
}
@inline(__always) private func write(_ output: String) {
FileHandle.standardOutput.write(output.data(using: .utf8)!)
}
}
//시간 줄인요소
//1. Wapas님 입출력
//2. print() result에 모아서 한번에 출력
let file = FileIO()
var m = file.readInt()
var bit = 0
var result = ""
while m != 0{
// let oper = file.readStirngSum()
// let x = file.readInt()
switch file.readStirngSum(){
case 297:
bit |= (1 << file.readInt())
case 654:
bit &= ~(1 << file.readInt())
case 510:
if (bit & (1 << file.readInt()) != 0){
result.append("1\n")
}else{
result.append("0\n")
}
case 642:
bit ^= (1 << file.readInt())
case 313:
bit |= (~0)
case 559:
bit &= 0
default:
break
}
m -= 1
}
print(result)
'Algorithm > 문제풀이_백준' 카테고리의 다른 글
[Swift][DFS] 백준 1248번 (맞춰봐) (0) | 2022.03.15 |
---|---|
[Swift][DP] 백준 5582번 (공통 부분 문자열) (0) | 2022.03.14 |
[Swift][DP] 백준 9251번 (LCS) (0) | 2022.03.10 |
[Swift][BFS] 백준 16946번 (벽 부수고 이동하기4) (0) | 2022.03.07 |
[Swift][DP] 백준 11058번 (크리보드) (0) | 2022.03.02 |
댓글