Acm/Icpc Cheatsheet: Puzzles
Acm/Icpc Cheatsheet: Puzzles
Puzzles
Contents
1 STL Useful Tips 2
1.1 Common libraries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Useful constant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.4 Space waster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.5 Tricks in cmath . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.6 Initialize array with predefined value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.7 Modifying sequence operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.8 Merge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.9 String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.10 Heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.11 Sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.12 Permutations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.13 Searching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.14 Random algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2 Number Theory 6
2.1 Prime number under 100 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Max or min . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3 Greatest common divisor — GCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.4 Least common multiple — LCM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.5 If prime number . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.6 Prime factorization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.7 Leap year . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.8 Binary exponiential . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.9 ab mod p . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.10 Factorial mod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.11 Generate combinations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.12 10-ary to m-ary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.13 m-ary to 10-ary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.14 Binomial coefficient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.15 Catalan numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.16 Eulerian numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.17 Karatsuba algorithm in Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.18 Euler’s totient function . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
2.19 Split plane . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3 Searching Algorithms 11
3.1 Find rank k in array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.2 KMP Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
4 Dynamic Programming 13
4.1 0/1 Knapsack problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
4.2 Complete Knapsack problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
4.3 Longest common subsequence (LCS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.4 Longest increasing common sequence (LICS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.5 Longest Increasing Subsequence (LIS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.6 Maximum submatrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.7 Partitions of integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.8 Partitions of sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
5 Trees 17
5.1 Tree traversal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
5.2 Depth and width of tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
6 Graph Theory 19
6.1 Graph representation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
6.2 Flood fill algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
6.3 SPFA — shortest path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
6.4 Floyd-Warshall algorithm – shortest path of all pairs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
6.5 Prim — minimum spanning tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
6.6 Eulerian circuit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
6.7 Topological sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.2 I/O
INT_MIN
INT_MAX
LONG_MIN
LONG_MAX
LLONG_MIN
LLONG_MAX
(~0u) // infinity (for long and long long)
// use (~0u)>>2 for int.
1.4 Space waster
// function definitions
// rest of program
1.8 Merge
1.9 String
// Searching
unsigned int find(const string &s2, unsigned int pos1 = 0);
unsigned int rfind(const string &s2, unsigned int pos1 = end);
unsigned int find_first_of(const string &s2, unsigned int pos1 = 0);
unsigned int find_last_of(const string &s2, unsigned int pos1 = end);
unsigned int find_first_not_of(const string &s2, unsigned int pos1 = 0);
unsigned int find_last_not_of(const string &s2, unsigned int pos1 = end);
// Insert, Erase, Replace
string& insert(unsigned int pos1, const string &s2);
string& insert(unsigned int pos1, unsigned int repetitions, char c);
string& erase(unsigned int pos = 0, unsigned int len = npos);
string& replace(unsigned int pos1, unsigned int len1, const string &s2);
string& replace(unsigned int pos1, unsigned int len1, unsigned int repetitions, char c);
// String streams
stringstream s1;
int i = 22;
s1 << "Hello world! " << i;
cout << s1.str() << endl;
1.10 Heap
// if you want to sort based on key, you need to copy the data to a vector
// where elements of vector are pair.
// you can define a PAIR type by using:
typedef pair<char, int> PAIR;
// sort data
sort(b.begin(), b.end(), cmp_by_value);
1.12 Permutations
srand(time(NULL));
// generate random numbers between [a,b)
rand() % (b - a) + a;
// generate random numbers between [0,b)
rand() % b;
// generate random permutations
random_permutation(anArray, anArray + 10);
random_permutation(aVector, aVector + 10);
2 Number Theory
2.1 Prime number under 100
bool prime(int n)
{
if (n<2) return false;
if (n<=3) return true;
if (!(n%2) || !(n%3)) return false;
for (int i=5;i*i<=n;i+=6)
if (!(n%i) || !(n%(i+2))) return false;
return true;
}
// complete factorization
int r;
while (n>1)
{
r = factor(n);
printf("%d", r);
n /= r;
}
bool isLeap(int n)
{
if (n%100==0)
if (n%400==0) return true;
else return false;
2.9 ab mod p
//n! mod p
int factmod (int n, int p) {
long long res = 1;
while (n > 1) {
res = (res * powmod (p-1, n/p, p)) % p;
for (int i=2; i<=n%p; ++i)
res=(res*i) %p;
n /= p;
}
return int (res % p);
}
k=m;
while ((k>0) && (n-a[k]==m-k)) k--;
if (k==0) break;
a[k]++;
for (int i=k+1;i<=m;i++)
a[i]=a[i-1]+1;
}
}
char a[16]={’0’,’1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’,
’A’,’B’,’C’,’D’,’E’,’F’};
return result;
}
string num="0123456789ABCDE";
return result;
}
n−1
X 1 n
Cn = Ck Cn−1−k = (1)
n+1 k
k=0
The first terms of this sequence are 2, 5, 14, 42, 132, 429, 1430 when C0 = 1. This is the number of ways to build a balanced
formula from n sets of left and right parentheses. It is also the number of triangulations of a convex polygon, the number of
rooted binary tress on n + 1 leaves and the number of paths across a lattice which do not rise above the main diagonal.
// This is the number of permutations of length n with exactly k ascending sequences or runs.
// Basis: k=0 has value 1
#define MAXN 100 // largest n or k
long eularian(n,k)
int n,m;
{
int i,j;
long e[MAXN][MAXN];
for (i=0; i<=n; i++) e[i][0] = 1;
for (j=0; j<=n; j++) e[0][j] = 0;
for (i=1; i<=n; i++)
for (j=1; j<i; j++)
e[i][j] = k*e[i-1][j] + (i-j+1)*e[i-1][j-1];
return e[n][k];
}
class Karatsuba {
private final static BigInteger ZERO = new BigInteger("0");
public static BigInteger karatsuba(BigInteger x, BigInteger y)
{
int N = Math.max(x.bitLength(), y.bitLength());
if (N <= 2000) return x.multiply(y);
N=(N/2)+(N %2);
BigInteger b = x.shiftRight(N);
BigInteger a = x.subtract(b.shiftLeft(N));
BigInteger d = y.shiftRight(N);
BigInteger c = y.subtract(d.shiftLeft(N));
BigInteger ac = karatsuba(a, c);
BigInteger bd = karatsuba(b, d);
BigInteger abcd = karatsuba(a.add(b), c.add(d));
return ac.add(abcd.subtract(ac).subtract(bd).shiftLeft(N)).add(bd.shiftLeft(2*N));
}
// the positive integers less than or equal to n that are relatively prime to n.
int phi (int n)
{
int result = n;
for (int i=2; i*i<=n; ++i)
if(n %i==0)
{
while(n %i==0)
n /= i;
result -= result / i;
}
if (n > 1)
result -= result / n;
return result;
}
3 Searching Algorithms
3.1 Find rank k in array
#include <iostream>
#include <string>
#include <vector>
buildTable(w, t);
while(m+i < s.length())
{
if(w[i] == s[m+i])
{
i++;
if(i == w.length()) return m;
}
else
{
m += i-t[i];
if(i > 0) i = t[i];
}
}
return s.length();
}
int main(void)
{
string a = (string) "The example above illustrates the general technique for assembling "+
"the table with a minimum of fuss. The principle is that of the overall search: "+
"most of the work was already done in getting to the current position, so very "+
"little needs to be done in leaving it. The only minor complication is that the "+
"logic which is correct late in the string erroneously gives non-proper "+
"substrings at the beginning. This necessitates some initialization code.";
string b = "table";
return 0;
}
4 Dynamic Programming
4.1 0/1 Knapsack problems
#include<iostream>
int f[1000]={0};
int n=0, m=0;
int main(void)
{
cin >> n >> m;
return 0;
}
#include<iostream>
int f[1000]={0};
int n=0, m=0;
int main(void)
{
cin >> n >> m;
return 0;
}
int dp[1001][1001];
#include<iostream>
int a[100]={0};
int b[100]={0};
int f[100]={0};
int n=0, m=0;
int main(void)
{
cin >> n;
for (int i=1;i<=n;i++) cin >> a[i];
cin >> m;
for (int i=1;i<=m;i++) cin >> b[i];
int ans=0;
for (int i=1;i<=m;i++)
if (f[i]>ans) ans=f[i];
return 0;
}
#include<iostream>
int n=0;
int a[100]={0}, f[100]={0}, x[100]={0};
int main(void)
{
cin >> n;
for (int i=1;i<=n;i++)
{
cin >> a[i];
x[i]=INT_MAX;
}
f[0]=0;
int ans=0;
for(int i=1;i<=n;i++)
{
int l=0, r=i;
while (l+1<r)
{
int m=(l+r)/2;
if (x[m]<a[i]) l=m; else r=m;
// change to x[m]<=a[i] for non-decreasing case
}
f[i]=l+1;
x[l+1]=a[i];
if (f[i]>ans) ans=f[i];
}
return 0;
}
int a[150][150]={0};
int c[200]={0};
int maxarray(int n)
{
int b=0, sum=-100000000;
for (int i=1;i<=n;i++)
{
if (b>0) b+=c[i];
else b=c[i];
if (b>sum) sum=b;
}
return sum;
}
int maxmatrix(int n)
{
int sum=-100000000, max=0;
return sum;
}
int main(void)
{
int n=0;
cin >> n;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
cin >> a[i][j];
where
n n
= =1 (4)
1 n
5 Trees
5.1 Tree traversal
int L[100]={0};
int R[100]={0};
void DLR(int m)
{
cout << m << " ";
if (L[m]!=0) DLR(L[m]);
if (R[m]!=0) DLR(R[m]);
}
void LDR(int m)
{
if (L[m]!=0) LDR(L[m]);
cout << m << " ";
if (R[m]!=0) LDR(R[m]);
}
void LRD(int m)
{
if (L[m]!=0) LRD(L[m]);
if (R[m]!=0) LRD(R[m]);
cout << m << " ";
}
int main(void)
{
cin >> n;
for (int i=1;i<=n;i++)
cin >> L[i] >> R[i];
DLR(1); cout << endl;
LDR(1); cout << endl;
LRD(1); cout << endl;
return 0;
}
#include <iostream>
#include <queue>
#include <stack>
int l[100]={0};
int r[100]={0};
stack<int> mystack;
int n=0;
int w=0;
int d=0;
int depth(int n)
{
if (l[n]==0 && r[n]==0)
return 1;
int depthl=depth(l[n]);
int depthr=depth(r[n]);
int dep=depthl>depthr ? depthl:depthr;
return dep+1;
}
void width(int n)
{
if (n<=d)
{
int t=0,x;
stack<int> tmpstack;
while (!mystack.empty())
{
x=mystack.top();
mystack.pop();
if (x!=0)
{
t++;
tmpstack.push(l[x]);
tmpstack.push(r[x]);
}
}
w=w>t?w:t;
mystack=tmpstack;
width(n+1);
}
}
int main(void)
{
cin >> n;
d=depth(1);
mystack.push(1);
width(1);
return 0;
}
6 Graph Theory
6.1 Graph representation
// Special structure here is usually not a typical graph, like city-blocks, triangles
// They are represented in 2-d array and shows weights on nodes instead of edges.
// Note that in this case travel through edge has no cost, but visit node has cost.
// Simple city-blocks: it’s just like first form of adjacency matrix, but this time
// represents weights on nodes, may not be square matrix.
// 1 2 4 5 6
// 2 4 5 1 3
// 4 5 2 3 6
for (int i=1;i<=n;i++)
for (int j=1;<=m;j++)
cin >> a[i][j];
// More complex data structures: typical city-block structure may has some constraints on
// questions, but it has no boundaries. However, some questions requires to form a maze.
// In these cases, data structures can be very flexible, it totally depends on how the question
// presents the data. A usual way is to record it’s adjacent blocks information:
struct Block{
bool l[4]; // if has 8 neighbors then use bool l[8];
// label them as your favor, e.x.
// 1 1 2 3
// 4 x 2 8 x 4
// 3 7 6 5
// true if there is path, false if there is boundary
// other informations (optional)
int weight;
int component_id;
// etc.
};
// Note that usually we use array from index 1 instead of 0 because sometimes
// you need index 0 as your boundary, and start from index 1 will give you
// advantage on locating nodes or positions
void find_components()
num_components = 0
for all nodes i
component(node i) = nil
for all nodes i
if component(node i) is nil
num_components = num_components + 1
component(i) = -2
flood_fill(component num_components)
int main(void)
{
int n=0, m=0;
cin >> n >> m;
return 0;
}
while (h!=t)
{
h++;
if (h>3000) h=1;
u=q[h];
for (int j=1; j<=a[u][0];j++)
{
v=a[u][j];
if (d[u]+w[u][v]<d[v]) // change to > if calculating longest path
{
d[v]=d[u]+w[u][v];
if (!f[v])
{
t++;
if (t>3000) t=1;
q[t]=v;
f[v]=true;
}
}
}
f[u]=false;
}
}
// map[i][j]=infinity at start
void floyd()
{
for (int k=1; k<=n; k++)
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++)
if (i!=j && j!=k && i!=k)
if (map[i][k]+map[k][j]<map[i][j])
map[i][j]=map[i][k]+map[k][j];
}
int d[1001]={0};
bool v[1001]={0};
int a[1001][1001]={0};
int main(void)
{
int n=0;
cin >> n;
for (int i=1;i<=n;i++)
{
int x=0, y=0, z=0;
cin >> x >> y >> z;
a[x][y]=z;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
if (a[i][j]==0) a[i][j]=INT_MAX;
d[u]=0;
int i=u;
while (i!=0)
{
v[i]=true;k=0;
mst+=d[i];
for (int j=1;j<=n;j++)
if (!v[j])
{
if (a[i][j]<d[j]) d[j]=a[i][j];
if (d[j]<d[k]) k=j;
}
i=k;
}
return mst;
}
void dfs(int k)
{
for (int i=1;i<=n;i++)
if (g[k][i])
{
g[k][i]=false;
g[i][k]=false;
dfs(i);
}
m++;
ans[m]=k;
}
int main(void)
{
cin >> n >> m;
m=0;
int k1=0;
for (int i=1;i<=n;i++)
{
if (f[i]%2==1) k1++;
if (k1>2)
{
cout << "error" << endl;
return 0;
}
if (f[i]%2 && c==0) c=i;
}
if (c==0) c=1;
dfs(x);
void dfs(int k)
{
int i=0;
v[k]=true;
for (int i=1;i<=n;i++)
if (g[k][i] && !v[i]) dfs(i);
m++;
ans[m]=k;
}
int main(void)
{
cin >> n >> m;
m=0;
for (int i=1;i<=n;i++)
if (!v[i]) dfs(i);
int main(void)
{
cin >> n >> m;
if (f[j]!=0)
{
cout << "error" << endl;
return 0;
}
ans[i]=j;
v[j]=true;
for (int k=1;k<=n;k++)
if (g[j][k]) f[k]--;
}
}
for (int i=1;i<=n;i++) cout << ans[i] << endl;
return 0;
}