CF Problem Sets
Posted on January 1, 2013
Tags: algorithms
1 Template
2 IO
2.1 Trivial
= list(map(int, input().split()))
a, b print(a+b)
package main
import("fmt")
func main(){
var a int
var b int
.Scanf("%d %d", &a, &b)
fmt}
#include <bits/stdc++.h>
using namespace std;
int main() {
int a,b;
("%d %d",&a,&b);
scanf}
2.2 Input list
4 100 93 48 59 2
int TC, goal;
std::vector<int> choice;
("%d %d",&TC,&goal);
scanfwhile (TC--){
int tmp;
("%d",&tmp);
scanf.push_back(tmp);
choice}
//TC is 4
//goal is 100
//choice is vector {93,48,59,2}
2.3 Input w/ TC count
TC
is Number of test cases given for us to process.
3 <--IN TC
1 5 <--IN
sum: 6 <--OUT
3 6 <--IN
sum: 9 <--OUT
4 8 <--IN sum: 12 <--OUT
= int(input())
TC for i in range(TC):
= list(map(int, input().split()))
a, b print(a+b)
package main
import("fmt")
func main(){
var TC int
.Scanln(&TC)
fmtfor i := 0; i < TC; i++ {
var a int
var b int
.Scanf("%d %d",&a,&b)
fmt.Printf("%d\n",a+b)
fmt}
}
#include <bits/stdc++.h>
using namespace std;
int main() {
int TC;
("%d", &TC);
scanfwhile (TC--){
int a,b;
("%d %d",&a,&b);
scanf("%d\n" a+b);
printf}
2.4 Input w/o TC count
- we arent given the count so we process input until we stop
while True:
try:
= list(map(int, input().split()))
a, b except:
break
print(a+b)
package main
import("fmt")
func main(){
var a int
var b int
for {
, err := fmt.Scanf("%d %d", &a, &b)
n.Printf("%d\n",a+b)
fmtif n == 0 || err != nil { break }
}
}
#include <bits/stdc++.h>
using namespace std;
int main() {
int a,b;
while (scanf("%d %d", &a, &b) != 0){
("%d\n", a+b);
printf}
//terminates when you input `/0`
2.5 Input w/ different sizes
2.6 File
INPUT OUTPUT
3 | 6
1 5 | 14
5 9 | 10 7 3 |
#include <bits/stdc++.h>
;
using namespace std
int main() {
// comment all lines and only uncomment demo code that you are interested with
"IO_in1.txt", "r", stdin);
freopen(int TC;
"%d", &TC); // number of test cases
scanf(while (TC--) { // shortcut to repeat until 0
int a, b; scanf("%d %d", &a, &b);
"%d\n", a+b); // compute on the fly
printf(
}return 0;
}
3 Create File and Read File
For Golang:
fmt.Scanln()
to read input into different KNOWN variablesbufio.Reader
to read full line w/ newline charbufio.Scanner
to read full line w/o newline char
package main
import (
"fmt"
"log"
"os"
)
func main() {
, err := os.ReadFile("file.txt")
contentif err != nil {
.Fatal(err)
log}
.Println(string(content))
fmt}
package main
import (
"fmt"
"io"
"os"
)
func main() {
,_ := os.Create("shit.txt")
fdefer f.Close()
.Copy(f,"AHHH")
io}
4 Data Structures
4.1 LinkedList - ProductType
- Product types are structs/records
struct linkedlist {
int val;
struct linkedlist* next;
};
void printList(struct linkedlist* head){
while((*head).next != NULL ){
("%d\n",(*head).val);
printf= (*head).next;
head }
("%d\n",(*head).val); //print last
printf}
int main(){
struct linkedlist a;
struct linkedlist b;
struct linkedlist c;
.val = 5;
a.val = 2;
b.val = 9;
c.next = &b;
a.next = &c;
b.next = NULL;
c(&a);
printList}
#include <bits/stdc++.h>
using namespace std;
struct LinkedList {
int x = 0;
* next;
LinkedList};
int main(){
std::cout << "hi";
struct LinkedList x ;
struct LinkedList a, b, c ;
->next = &a;
x
std::cout << x.x;
return 0;
}
package main
import(
"fmt"
)
type LinkedList[T any] struct {
Data T*LinkedList[T]
Next }
func (e *LinkedList[T]) Append(data T) *LinkedList[T] {
if e.Next == nil {
.Next = &LinkedList[T]{data, nil}
e} else {
:= &LinkedList[T]{data, e.Next}
tmp .Next = tmp
e}
return e.Next
}
func (e *LinkedList[T]) String() string {
return fmt.Sprintf("LinkedList: %v", e.Data)
}
func main(){
var b LinkedList[int]
.Data = 4
b.Println(b.String())
fmt}
class ListNode(object):
def __init__(self, val=0, next=None):
self.val = val
self.next = None
= ListNode(val=2)
a next = ListNode(val=5)
a.next.next = ListNode(val=9) a.
4.2 Adjacency list
= [[1,3],[3,4],[2],[5],[],[3]]
a
= [[0 for col in range(0,len(a))] for row in range(0,len(a))]
b
class Node:
def __init__(self,data):
self.children = []
self.data = data
def printout(self):
print(self.data)
def adjToMat(adj,mat):
for row,adjlist in enumerate(adj):
for col in adjlist:
= 1
mat[row][col] return mat
= adjToMat(a,b)
c
def prettyMat(x):
= " ".join([str(i) for i in range(0,len(x))])
colLabel print(f" {colLabel}")
for row,i in enumerate(x):
print(f"{row} {i}")
prettyMat(c)
# 0 1 2 3 4 5
# 0 [0, 1, 0, 1, 0, 0]
# 1 [0, 0, 0, 1, 1, 0]
# 2 [0, 0, 1, 0, 0, 0]
# 3 [0, 0, 0, 0, 0, 1]
# 4 [0, 0, 0, 0, 0, 0]
# 5 [0, 0, 0, 1, 0, 0]
5 Codeforces
5.1 698A - DP
= input()
nil = [int(x) for x in input().split()]
a = len(a)
n
= [[999999 for x in range(0,3)] for y in range(0,n)]
dp
= 0
REST = 1
GYM = 2
CODE
= 0
NO_CODEGYM = 1
NO_GYM = 2
NO_CODE = 3
YES_BOTH
def basecase():
0][REST] = 1
dp[if a[0] == NO_GYM or a[0] == YES_BOTH:
0][CODE] = 0
dp[if a[0] == NO_CODE or a[0] == YES_BOTH:
0][GYM] = 0
dp[
def restPrev(i):
=dp[i-1][REST]
restVal = dp[i-1][GYM]
gymVal = dp[i-1][CODE]
codeVal return 1 + min([restVal,gymVal,codeVal])
def codePrev(i):
=dp[i-1][REST]
restVal = dp[i-1][CODE]
codeVal return min([restVal,codeVal])
def gymPrev(i):
=dp[i-1][REST]
restVal = dp[i-1][GYM]
gymVal return min([restVal,gymVal])
def lastday(i):
=dp[i-1][REST]
restVal = dp[i-1][GYM]
gymVal = dp[i-1][CODE]
codeVal return min([restVal,gymVal,codeVal])
basecase()# print(dp)
for k in range(1,n):
#print(dp[k])
if a[k] == NO_CODEGYM:
= restPrev(k)
dp[k][REST] if a[k] == NO_CODE:
= restPrev(k)#optimal(rest) today is based on optimal(rest) yesterday
dp[k][REST] = codePrev(k)#optimal(gym) today is based on optimal(code) yesterday
dp[k][GYM] if a[k] == NO_GYM:
= restPrev(k)#optimal(rest) today is based on optimal(rest) yesterday
dp[k][REST] = gymPrev(k)#optimal(code) today is based on optimal(gym) yesterday
dp[k][CODE] if a[k] == YES_BOTH:
= restPrev(k)
dp[k][REST] = gymPrev(k)
dp[k][CODE] = codePrev(k)
dp[k][GYM]
print(lastday(n))
5.2 Takeaway
- Initialize all value in dp as INF or unoptimal
- look at the code, how does it account for rejecting 2 consecutive days?
- Notice that (gym) –depends–> (gym yesterday) BUT Optimal(gym) –depends–> (Optimal(rest) yesterday,Optimal(code) yesterday)
\[gym \overset{depends}{\rightarrow} gym_yesterday \tag{Red Herring}\] \[Optimal(gym) \overset{depends}{\rightarrow} (Optimal(code_yesterday),Optimal(rest_yesterday)) \tag{Correct}\]
Think about constraint WRT TO OPTIMALITY, not the action itself
6 YeetCode
6.1 LC91 Decoding
Question, How many ways we can decode the string with each word being either 1 or 2 letters.
- Lesson: How many ways = COUNT # paths in DFS from root to leaf. We can always cache memoize DFS.
"""
either terminate 1-next or terminate 2-next
(1|13..) or (11|3..)
ConstraintA: Reject 2-next when > "26"
ConstraintB: When 2-next is "0", must ONLY terminate 2-next NOT
(1|03) BAD
(10|3) GOOD
DFS, pruning bad decisions
2 possible cases
(..10)
(..04) if there is a 0 we must take it
"""
class Solution(object):
def numDecodings(self, s):
"""
:type s: str
:rtype: int
"""
def dfs(s):
if len(s) == 0:
return 1
if len(s) == 1:
if s == "0":
return 0
return 1
= s[:1]
take1 = s[1:]
rest1 = s[:2]
take2 = s[2:]
rest2 if take2[0] == "0":
return 0
if int(take2) > 26:
return dfs(rest1) + 0
if take1 == "0":
return 0
else:
return dfs(rest1) + dfs(rest2)
return dfs(s)
#TLE but correct
"""
either terminate 1-next or terminate 2-next
(1|13..) or (11|3..)
ConstraintA: Reject 2-next when > "26"
ConstraintB: When 2-next is "0", must ONLY terminate 2-next NOT
(1|03) BAD
(10|3) GOOD
ConstraintC: Reject 1-next when "0". This is no map from a single "0".
DFS, pruning bad decisions
2 possible cases
(..10)
(..04) if there is a 0 we must take it
"""
class Solution(object):
def numDecodings(self, s):
"""
:type s: str
:rtype: int
"""
def cache(func):
= {}
cache_ def wrapper(*args):
try:
return cache_[args]
except:
= func(*args)
cache_[args] return cache_[args]
return wrapper
@cache
def dfs(s):
if len(s) == 0:
return 1
if len(s) == 1:
if s == "0":
return 0
return 1
= s[:1]
take1 = s[1:]
rest1 = s[:2]
take2 = s[2:]
rest2 if take2[0] == "0":
return 0
if int(take2) > 26:
return dfs(rest1) + 0
if take1 == "0":
return 0
else:
return dfs(rest1) + dfs(rest2)
return dfs(s)
#SUCCESS due to cache memo
class Solution(object):
def numDecodings(self, s):
"""
:type s: str
:rtype: int
"""
= {}
memo def dfs(s):
if len(s) == 0:
return 1
if len(s) == 1:
if s == "0":
return 0
return 1
= s[:1]
take1 = s[1:]
rest1 = s[:2]
take2 = s[2:]
rest2 if take2[0] == "0":
return 0
if int(take2) > 26:
= -999
dfsOUT1 if rest1 in memo:
= memo[rest1] + 0
dfsOUT1else:
= dfs(rest1)
memo[rest1] = memo[rest1] + 0
dfsOUT1 return dfsOUT1
if take1 == "0":
return 0
else:
= -999
dfsOUT1 = -999
dfsOUT2 if rest1 in memo:
= memo[rest1]
dfsOUT1 else:
= dfs(rest1)
memo[rest1] = memo[rest1]
dfsOUT1 if rest2 in memo:
= memo[rest2]
dfsOUT2 else:
= dfs(rest2)
memo[rest2] = memo[rest2]
dfsOUT2 return dfsOUT1 + dfsOUT2
#return dfs(rest1) + dfs(rest2)
return dfs(s)
#Even faster than decorator memo for somereason
using std::string;
(string mystr){
string tailreturn mystr.substr(1);
}
int minDistanceR(string word1, string word2){
if(word2.size() == 0){
return word1.size();
}
if(word1.size() == 0){
return word2.size();
}
= tail(word1);
string tail1 = tail(word2);
string tail2 = string(1,word1[0]);
string head1 = string(1,word2[0]);
string head2 if (head1 == head2){
int cost = 0;
int opt_Match = cost + minDistanceR(tail1,tail2);
return opt_Match;
}
if (head1 != head2){
int cost = 1;
int opt_Insert = cost + minDistanceR(word1,tail2);
int opt_Del = cost + minDistanceR(tail1,word2);
int opt_Subst = cost + minDistanceR(tail1,tail2);
return std::min(opt_Subst,std::min(opt_Insert,opt_Del));
}
return 0;
}
6.2 LC1299
- Replace Elements with Greatest Element on Right Side
class Solution:
def replaceElements(self, arr: List[int]) -> List[int]:
= -1
rMax for i in range(len(arr) - 1, -1, -1):
= max(rMax,arr[i])
newMax = rMax
arr[i] = newMax
rMax return arr
impl Solution {
pub fn replace_elements(arr: Vec<i32>) -> Vec<i32> {
let mut rMax = -1;
let mut arrT = arr;
for i in (0..arrT.len()).rev(){
let mut newMax = std::cmp::max(rMax, arrT[i]);
= rMax;
arrT[i] = newMax;
rMax }
return arrT
}
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func replaceElements(arr []int) []int {
var rMax int
= -1
rMax for i := len(arr)-1; i > -1; i-- {
:= max(rMax,arr[i])
newMax [i] = rMax
arr= newMax
rMax }
return arr
}
function replaceElements(arr: number[]): number[] {
: number = -1
let rMaxfor (let i: number = arr.length-1; i > -1; i--){
: number = Math.max(rMax,arr[i])
let newMax= rMax
arr[i] = newMax
rMax
}
return arr; }
7 UVA
7.1 495 fib
- To return arrays in C++, you must return pointer
- all function local var are destroyed in C++ unlike python or JS.
- This means you cant initialize an array in a function and hope to return it for use in main
int* fib(int dp[]){
[0] = 1;
dp[1] = 1;
dpfor(int i = 2; i < 5001; i++){
[i] = dp[i-1]+dp[i-2];
dp}
return dp;
}
using std::cin;
int main(){
int dp[5001];
(dp);
fib(dp[4]);
printint n;
while(cin >> n){
(dp[n]);
print}
}
8 Fr
8.1 Closest values in list
def closestvalues(L):
L.sort()= min(((L[i]-L[i-1]),i) for i in range(1,len(L)))
valmin,argmin return L[argmin-1],L[argmin]
print(closestvalues([6,4,8,7,3,5]))
8.2 Counting sort
sort using O(n) by throwing stuff at an ordered hashmap
def countingsort(L):
= max(L)
mymax = {}
mydic for i in range(0,mymax+1):
= 0
mydic[i] for j in L:
= mydic[j] + 1
mydic[j] = []
output for k,v in mydic.items():
for c in range(0,v):
output.append(k)return output
print(countingsort([1,7,6,7,84,35,5]))
Given a list of intervals, find a point that is included in max # of intervals.
def maxinterval(S):
= [(left,+1) for (left,right) in S] + [(right,-1) for (left,right) in S]
bounds =lambda x: x[0])
bounds.sort(key= 0
partSol = (partSol, None)
best for (startbound,energy) in bounds:
+= energy
partSol if best[0] < partSol:
= (partSol,startbound)
best return best
print(maxinterval([(1,5),(3,6),(5,8),(6,9),(5,10)]))