AcWing 算法基础课 C++ 学习

10 篇文章 21 订阅

Day 1 (2022.5.14)

// AcWing 785. 快速排序

#include <iostream>

using namespace std;

const int N = 100010;

int q[N];

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;
    
    int i = l - 1, j = r + 1, x = q[(l + r) >> 1];
    
    while (i < j)
    {
        do i++; while (q[i] < x);
        do j--; while (q[j] > x);
        if (i < j) swap(q[i], q[j]);
    }
    
    quick_sort(q, l, j);
    quick_sort(q, j+1, r);
}

int main()
{
    int n;
    scanf("%d", &n);
    
    for (int i = 0; i < n; i++) scanf("%d", &q[i]);
    
    quick_sort(q, 0, n - 1);
    
    for (int i = 0; i < n; i++) printf("%d ", q[i]);
    
    return 0;
}

Day 2 (2022.5.15)

// AcWing 787. 归并排序

#include <iostream>

using namespace std;

const int N = 1e5 + 10;

int a[N], tmp[N];

void merge_sort(int q[], int l, int r)
{
    if (l>=r) return;
    
    int mid = (l+r)/2;
    merge_sort(q, l, mid);
    merge_sort(q, mid+1, r);
    
    int k = 0, i = l, j = mid+1;
    while (i <= mid && j <= r)
        if (q[i] <= q[j]) tmp[k++] = q[i++];
        else tmp[k++] = q[j++];
    while (i <= mid) tmp[k++] = q[i++];
    while (j <= r) tmp[k++] = q[j++];
    
    for (i = l, j = 0; i <= r; i++, j++) q[i] = tmp[j];
}

int main()
{
    int n;
    scanf("%d", &n);
    
    for (int i = 0; i < n; i++) scanf("%d", &a[i]);
    
    merge_sort(a, 0, n-1);
    
    for (int i = 0; i < n; i++) printf("%d ", a[i]);
    
    return 0;
}

Day 3 (2022.5.16)

// AcWing 788. 逆序对的数量

#include <iostream>

using namespace std;

typedef long long LL;
LL cnt;

const int N = 1e5 + 10;
int a[N], tmp[N];

void merge_sort(int q[], int l, int r)
{
    if (l>=r) return;
    int mid = (l+r)/2;
    
    merge_sort(q, l, mid);
    merge_sort(q, mid+1, r);
    
    int k = 0, i = l, j = mid+1;
    while (i<=mid && j<=r)
        if (q[i] <= q[j]) tmp[k++] = q[i++];
        else 
        {
            tmp[k++] = q[j++];
            cnt += mid - i + 1;
        }
    while (i<=mid) tmp[k++] = q[i++];
    while (j<=r) tmp[k++] = q[j++];
    
    for (k=0; l<=r; l++, k++) q[l] = tmp[k];
}

int main()
{
    int n;
    scanf("%d", &n);
    
    for (int i = 0; i < n; i++) scanf("%d", &a[i]);
    
    merge_sort(a, 0, n-1);
    
    printf("%lld", cnt);
    
    return 0;

}
// AcWing 789. 数的范围

#include <iostream>

using namespace std;

const int N = 100010;

int a[N], n;

void binary_search(int q)
{
    int l = 0, r = n-1;
    while (l<r)
    {
        int mid = (l+r)/2;
        if (a[mid] >= q) r = mid;
        else l = mid + 1;
    }
    
    if (a[l] == q) printf("%d ", l);
    else
    {
        printf("-1 -1\n");
        return;
    }
    
    l = 0, r = n-1;
    while (l<r)
    {
        int mid = (l+r+1) / 2;
        if (a[mid] <= q) l = mid;
        else r = mid - 1;
    }
    printf("%d\n", l);
}

int main()
{
    int k, q;
    scanf("%d%d", &n, &k);
    
    for (int i = 0; i < n; i++) scanf("%d", &a[i]);
    
    while (k--)
    {
        scanf("%d", &q);
        bi_search(q);
    }
}
/ AcWing 790. 数的三次方根

#include <iostream>

using namespace std;

int main()
{
    double x;
    cin >> x;

    double l = -100, r = 100;
    while (r - l > 1e-8)
    {
        double mid = (l + r) / 2;
        if (mid * mid * mid >= x) r = mid;
        else l = mid;
    }

    printf("%.6lf\n", l);
    return 0;
}

Day 4 (2022.5.17)

// AcWing 791. 高精度加法

#include <iostream>
#include <vector>

using namespace std;

const int N = 1e5 + 10;

vector<int> add(vector<int>& A, vector<int>& B)
{
    vector<int> C;
    int t = 0;
    
    for (int i = 0; i < A.size() || i < B.size(); i++)
    {
        if (i < A.size()) t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }
    
    if (t) C.push_back(1);
    
    return C;
}

int main()
{
    vector<int> A, B;
    string a, b;
    
    cin >> a >> b;
    
    for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
    for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');

    auto res = add(A, B);
    
    for (int i = res.size() - 1; i >= 0; i--) printf("%d", res[i]);
    
    return 0;
}

Day 5 (2022.5.18)

C++实现整数除法向上取整 (a + b - 1) / b

// AcWing 792. 高精度减法

#include <iostream>
#include <vector>

using namespace std;

bool cmp(vector<int>& A, vector<int>& B)
{
    if (A.size() != B.size()) return A.size() > B.size();
    for (int i = A.size() - 1; i >= 0; i--)
    {
        if (A[i] != B[i]) return A[i] > B[i];
    }
    return true;
}

vector<int> sub(vector<int>& A, vector<int>& B)
{
    vector<int> C;
    int t = 0;
    
    for (int i = 0; i < A.size() || i < B.size(); i++)
    {
        if (i < A.size()) t += A[i];
        if (i < B.size()) t -= B[i];
        C.push_back((t + 10) % 10);
        if (t < 0) t = -1;
        else t = 0;
    }
    
    if (t) C.push_back(t);
    
    while(C.size() > 1 && C.back() == 0) C.pop_back();
    
    return C;
}

int main()
{
    string a, b;
    vector<int> A, B;
    cin >> a >> b;
    
    for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
    for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');
    
    vector<int> res;
    if (cmp(A, B)) res = sub(A, B);
    else
    {
        res = sub(B, A);
        printf("-");
    }
    
    
    for (int i = res.size() - 1; i >= 0; i--) printf("%d", res[i]);
    
    return 0;
}

Day 6 (2022.5.19)

// AcWing 793. 高精度乘法

#include <iostream>
#include <vector>
#include <string>

using namespace std;

const int N = 1e6 + 10;
vector<int> A;

vector<int> multiple(vector<int>& A, int b)
{
	vector<int> res;
    int t = 0;
    for (int i = 0; i < A.size(); i++)
    {
        t += A[i] * b;
        res.push_back(t % 10);
        t /= 10;
    }

    while (t)
    {
        res.push_back(t % 10);
        t /= 10;
    }
    
    while (res.size() > 1 && res.back() == 0) res.pop_back();
        
	return res;
}

int main()
{
	string s;
	int a;

	cin >> s >> a;
	for (int i = s.size() - 1; i > -1; i--) A.push_back(s[i] - '0');

	vector<int> res = multiple(A, a);
	
	for (int i = res.size() - 1; i > -1; i--) printf("%d", res[i]);
	
	return 0;
}

Day 7 (2022.5.22)

// AcWing 794. 高精度除法

#include <iostream>
#include <vector>
#include <string>

using namespace std;

vector<int> divide(vector<int> A, int& b)
{
    vector<int> res;
    int t = 0;
    for (int i = A.size() - 1; i > -1; i--)
    {
        t = t * 10 + A[i];
        res.push_back(t / b);
        t %= b;
    }
    
    while (res.size() > 1 && res[0] == 0) res.erase(res.begin());
    
    b = t;
    return res;
}

int main()
{
    vector<int> A;
    int b;
    string s_a;
    
    cin >> s_a >> b;
    for (int i = s_a.size() - 1; i > -1; i--) A.push_back(s_a[i] - '0');
    
    vector<int> res = divide(A, b);
    
    for (int i = 0; i < res.size(); i++) cout << res[i];
    cout << endl << b;
    
    return 0;
}
// AcWing 795. 前缀和


#include <cstdio>

const int N = 100010;
int a[N];

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i < n + 1; i++) scanf("%d", &a[i]);
    for (int i = 2; i < n + 1; i++) a[i] += a[i-1];
    
    int l, r;
    while (m--)
    {
        scanf("%d%d", &l, &r);
        printf("%d\n", a[r] - a[l-1]);
    }
    
    return 0;
}
// AcWing 796. 子矩阵的和


#include <cstdio>

const int N = 1010;
int a[N][N];

int main()
{
    int n, m, q;
    scanf("%d%d%d", &n, &m, &q);
    for (int i = 1; i < n + 1; i++)
        for (int j = 1; j < m + 1; j++)
            scanf("%d", &a[i][j]);
    
    for (int i = 1; i < n + 1; i++)
    {
        for (int j = 1; j < m + 1; j++)
        {
            a[i][j] += a[i-1][j] + a[i][j-1] - a[i-1][j-1];
        }
    }
        
            
    int x1, y1, x2, y2;
    while (q--)
    {
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        printf("%d\n", a[x2][y2] - a[x2][y1-1] - a[x1-1][y2] + a[x1-1][y1-1]);
    }
    
    return 0;
}

Day 8 (2022.5.23)

// AcWing 797. 差分


#include <cstdio>

const int N = 100010;
int a[N];

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    
    for (int i = 1; i < n + 1; i++) scanf("%d", &a[i]);
    for (int i = n; i > 1; i--) a[i] -= a[i-1];
    
    
    int l, r, c;
    while (m--)
    {
        scanf("%d%d%d", &l, &r, &c);
        a[l] += c;
        a[r+1] -= c;
    }
    
    for (int i = 1; i < n + 1; i++)
    {
        a[i] += a[i-1];
        printf("%d ", a[i]);
    }
    return 0;
}

// AcWing 798. 差分矩阵


// 用插入的方法构造初始二维差分数组

#include <cstdio>

const int N = 1010;
int a[N][N], q[N][N];

void insert(int x1, int y1, int x2, int y2, int c)
{
    q[x1][y1] += c;
    q[x2+1][y1] -= c;
    q[x1][y2+1] -= c;
    q[x2+1][y2+1] += c;
}

int main()
{
    int n, m, t;
    scanf("%d%d%d", &n, &m, &t);
    
    for (int i = 1; i < n + 1; i++)
        for (int j = 1; j < m + 1; j++)
            scanf("%d", &a[i][j]);
    
    for (int i = 1; i < n + 1; i++)
        for (int j = 1; j < m + 1; j++)
            insert(i, j, i, j, a[i][j]);
    
    int x1, y1, x2, y2, c;
    while (t--)
    {
        scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &c);
        insert(x1, y1, x2, y2, c);
    }
    
    for (int i = 1; i < n + 1; i++)
    {
        for (int j = 1; j < m + 1; j++)
        {
            q[i][j] += q[i-1][j] + q[i][j-1] - q[i-1][j-1];
            printf("%d ", q[i][j]);
        }
        printf("\n");
    }
        
    return 0;
}
// AcWing 799. 最长连续不重复子序列

#include <cstdio>
#include <algorithm>

const int N = 100010;
int a[N], q[N];

int main()
{
    int n, m_max = 0;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) scanf("%d", &a[i]);
    
    int i = 0, j = 0;
    while (j < n)
    {
        q[a[j]] += 1;
        while (q[a[j]] != 1)
        {
            q[a[i]] -= 1;
            i++;
        }
        m_max = std::max(m_max, j - i + 1);
        j++;
    }
    
    printf("%d", m_max);
    return 0;
}

Day 9 (2022.5.24)

// AcWing 800. 数组元素的目标和

#include <iostream>

const int N = 1e5 + 10;

int a[N], b[N];

int main()
{
    int n, m, x;
    scanf("%d%d%d", &n, &m, &x);
    
    for (int i = 0; i < n; i++) scanf("%d", &a[i]);
    for (int i = 0; i < m; i++) scanf("%d", &b[i]);
    
    int i = 0, j = m - 1, t;
    
    while (t = a[i] + b[j], t != x)
    {
        if (j > 0 && t > x) j--;
        else i++;
    }
    
    printf("%d %d\n", i, j);
    return 0;
}
// AcWing 2816. 判断子序列


#include <cstdio>

const int N = 1e5 + 10;

int a[N], b[N];

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    
    for (int i = 0; i < n; i++) scanf("%d", &a[i]);
    for (int i = 0; i < m; i++) scanf("%d", &b[i]);
    
    int i = 0, j = 0;
    while (i < n && j < m)
    {
        if (a[i] == b[j]) i++, j++;
        else j++;
    }
    
    if (i == n) printf("Yes");
    else printf("No");
    
    return 0;
}
// AcWing 801. 二进制中1的个数


#include <cstdio>

int main()
{
    int n, cnt = 0, x;
    scanf("%d", &n);
    
    while (n--)
    {
        scanf("%d", &x);
        for (; x; x -= x & -x) cnt++;
        printf("%d ", cnt);
        cnt = 0;
    }
    return 0;
}
// AcWing 802. 区间和


#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

typedef pair<int, int> PII;

const int N = 3e5 + 10;

int a[N];

vector<int> alls;
vector<PII> add, query;

int find(int x)
{
    int l = 0, r = alls.size() - 1;
    while (l < r)
    {
        int mid = (l + r) / 2;
        if (alls[mid] >= x) r = mid;
        else l = mid + 1;
    }
    return l + 1;
}

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    
    int x, c;
    for (int i = 0; i < n; i++)
    {
        scanf("%d%d", &x, &c);
        add.push_back({x, c});
        
        alls.push_back(x);
    }
    
    int l, r;
    for (int i = 0; i < m; i++)
    {
        scanf("%d%d", &l, &r);
        query.push_back({l, r});
        
        alls.push_back(l);
        alls.push_back(r);
    }
    
    sort(alls.begin(), alls.end());
    alls.erase(unique(alls.begin(), alls.end()), alls.end());
    
    for (auto item : add)
    {
        int x = find(item.first);
        a[x] += item.second;
    }
    
    for (int i = 1; i < alls.size() + 1; i++) a[i] += a[i-1];
    
    for (auto item : query)
    {
        int l = find(item.first), r = find(item.second);
        printf("%d\n", a[r] - a[l-1]);
    }
    
    return 0;
}

Day 10 (2022.5.25)

// AcWing 803. 区间合并


#include <cstdio>
#include <vector>
#include <limits.h>
#include <algorithm>

using namespace std;

typedef pair<int, int> PII;

vector<PII> a;

int main()
{
    int n;
    scanf("%d", &n);
    
    int l, r;
    while (n--)
    {
        scanf("%d%d", &l, &r);
        a.push_back({l, r});
    }
    
    sort(a.begin(), a.end());
    
    int cnt = 0, r = INT_MIN;
    
    
    for (auto item : a)
    {
        if (item.second > r)
        {
            if (r < item.first) cnt++;
            min = item.second;
        }
    }
    
    printf("%d", cnt);
    
    return 0;
}

Day 11 (2022.5.26)

// AcWing 826.单链表

#include <iostream>

const int N = 100010;

int head = -1, e[N], ne[N], idx = 0;

void add_to_head(int x)
{
    e[idx] = x, ne[idx] = head, head = idx++;
}

void remove(int k)
{
    ne[k] = ne[ne[k]];
}

void add(int k, int x)
{
    e[idx] = x, ne[idx] = ne[k], ne[k] = idx++;
}

int main()
{
    int n;
    scanf("%d\n", &n);
    
    int k, x;
    char op;
    while (n--)
    {
        scanf("%c", &op);
        if (op == 'H')
        {
            scanf("%d\n", &x);
            add_to_head(x);
        }
        else if (op == 'D')
        {
            scanf("%d\n", &k);
            if (!k) head = ne[head];
            else remove(k - 1);
        }
        else
        {
            scanf("%d%d\n", &k, &x);
            add(k - 1, x);
        }
    }
    
    while (head != -1)
    {
        printf("%d ", e[head]);
        head = ne[head];
    }
    
    return 0;
}

Day 12 (2022.5.27)

// AcWing 827.双链表

#include <iostream>
#include <string>

using namespace std;

const int N = 100010;
int l[N], r[N], e[N], idx = 2;

// 从左到右,从下到上
void insert(int k, int x)
{
	e[idx] = x, l[idx] = k, r[idx] = r[k], l[r[k]] = idx, r[k] = idx++;
}

void remove(int k)
{
	l[r[k]] = l[k], r[l[k]] = r[k];
}

int main()
{
	int n;
	scanf("%d", &n);
	l[1] = 0, r[0] = 1;

	string op;
	int k, x;
	while (n--)
	{
		cin >> op;
		if (op == "L")
		{
			cin >> x;
			insert(0, x);
		}
		else if (op == "R")
		{
			cin >> x;
			insert(l[1], x);
		}
		else if (op == "D")
		{
			cin >> k;
			remove(k + 1);
		}
		else if (op == "IL")
		{
			cin >> k >> x;
			insert(l[k + 1], x);
		}
		else
		{
			cin >> k >> x;
			insert(k + 1, x);
		}
	}

	for (int i = r[0]; i != 1; i = r[i]) cout << e[i] << " ";
	return 0;
}

Day 13 (2022.5.28)

// AcWing 828. 模拟栈

#include <stack>
#include <iostream>
#include <string>

using namespace std;

int main()
{
	stack<int> st;
	int n;
	cin >> n;

	string op;
	int x;
	while (n--)
	{
		cin >> op;
		if (op == "push")
		{
			cin >> x;
			st.push(x);
		}
		else if (op == "query")
		{
			cout << st.top() << endl;
		}
		else if (op == "pop")
		{
			st.pop();
		}
		else
		{
			if (st.empty()) cout << "YES" << endl;
			else cout << "NO" << endl;
		}
	}

	return 0;
}


// yxc 的方法

#include <iostream>

using namespace std;

const int N = 100010;

int m;
int stk[N], tt;

int main()
{
    cin >> m;
    while (m -- )
    {
        string op;
        int x;

        cin >> op;
        if (op == "push")
        {
            cin >> x;
            stk[ ++ tt] = x;
        }
        else if (op == "pop") tt -- ;
        else if (op == "empty") cout << (tt ? "NO" : "YES") << endl;
        else cout << stk[tt] << endl;
    }

    return 0;
}

Day 14 (2022.5.29)

// AcWing 3302. 表达式求值

#include <iostream>
#include <unordered_map>
#include <stack>
#include <algorithm>

using namespace std;

stack<int> num;
stack<int> op;

void eval()
{
    int b = num.top(); num.pop();
    int a = num.top(); num.pop();
    char c = op.top(); op.pop();
    
    int x;
    if (c == '+') x = a + b;
    else if (c == '-') x = a - b;
    else if (c == '*') x = a * b;
    else x = a / b;
    
    num.push(x);
}

int main()
{
    unordered_map<char, int> pr{{'+', 1}, {'-', 1}, {'*', 2}, {'/', 2}};
    string str;
    cin >> str;
    
    for (int i = 0; i < str.size(); i++)
    {
        char c = str[i];
        if (isdigit(c))
        {
            int x = 0, j = i;
            while (j < str.size() && isdigit(str[j]))
                x = x * 10 + str[j++] - '0';
            i = j - 1;
            num.push(x);
        }
        else if (c == '(') op.push(c);
        else if (c == ')')
        {
            while (op.top() != '(') eval();
            op.pop();
        }
        else
        {
            while (op.size() && op.top() != '(' && pr[op.top()] >= pr[c]) eval();
            op.push(c);
        }
    }
    
    while (op.size()) eval();
    cout << num.top() << endl;
    return 0;
}

Day 15 (2022.6.6)

// AcWing 829. 模拟队列

#include <iostream>
#include <string>

using namespace std;

const int N = 100010;

int a[N], head = 1, tail = 0;

int main()
{
	int n, x;
	string str;
	cin >> n;
	
	while (n--)
	{
		cin >> str;
		if (str == "push")
		{
			cin >> x;
			a[++tail] = x;
		}
		else if (str == "empty")
		{
			if (tail != head - 1) cout << "NO" << endl;
			else cout << "YES" << endl;
		}
		else if (str == "pop")
		{
			head++;
		}
		else
		{
			cout << a[head] << endl;
		}
	}

	return 0;
}

Day 16 (2022.6.7)

// AcWing 830. 单调栈

#include <iostream>
#include <stack>

using namespace std;

const int N = 100010;

int a[N];

int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) scanf("%d", &a[i]);
    
    stack<int> stk;
    
    for (int i = 0; i < n; i++)
    {
        while (!stk.empty())
        {
            if (stk.top() < a[i])
            {
                printf("%d ", stk.top());
                break;
            }
            else stk.pop();
        }
        if (stk.empty()) printf("-1 ");
        stk.push(a[i]);
    }
    
    return 0;
    
}
// AcWing 154. 滑动窗口

#include <iostream>
#include <deque>

using namespace std;

const int N = 1e6 + 10;
int a[N];
deque<int> q;

int main()
{
    int n, k;
    cin >> n >> k;
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &a[i]);
        if (i > k - 1 && q.front() < i - k + 1) q.pop_front();
        while (!q.empty())
        {
            if (a[q.back()] >= a[i]) q.pop_back();
            else break;
        }
        q.push_back(i);
        if (i >= k - 1) printf("%d ", a[q.front()]);
    }
    
    printf("\n"); q.clear();
    
    for (int i = 0; i < n; i++)
    {
        if (i > k - 1 && q.front() < i - k + 1) q.pop_front();
        while (!q.empty())
        {
            if (a[q.back()] <= a[i]) q.pop_back();
            else break;
        }
        q.push_back(i);
        if (i >= k - 1) printf("%d ", a[q.front()]);
    }
    
    
    return 0;
}

Day 17 (2022.6.18)

// AcWing 831. KMP字符串

#include <iostream>

using namespace std;

const int N = 100010, M = 1000010;

char s[M], p[N];
int n, m, ne[N];

int main()
{
    cin >> n >> p+1 >> m >> s+1;
    
    for (int i = 2, j = 0; i <= n; i++)
    {
        while (j && p[i] != p[j+1]) j = ne[j];
        if (p[i] == p[j+1]) j++;
        ne[i] = j;
    }
    
    for (int i = 1, j = 0; i <= m; i++)
    {
        while (j && s[i] != p[j+1]) j = ne[j];
        if (s[i] == p[j+1]) j++;
        if (j == n)
        {
            printf("%d ", i - n);
            j = ne[j];
        }
    }
    
    return 0;
}

Day 18 (2022.6.27)

// AcWing 835. Trie字符串统计

#include <iostream>
#include <string>
#include <map>

using namespace std;

map<string, int> m;

int main()
{
	int n;
	char op;
	string s;
	cin >> n;

	while (n--)
	{
		cin >> op >> s;
		if (op == 'I') m[s] = m[s] + 1;
		else cout << m[s] << endl;
	}

	return 0;
}


// ********************************************************* //

#include <iostream>
#include <string>

using namespace std;

const int N = 1e5 + 1;
int son[N][26], cnt[N], idx = 1;

void insert(string& s)
{
    int p = 0;
    for (int i = 0; i < s.size(); i++)
    {
        int u = s[i] - 'a';
        if (!son[p][u]) son[p][u] = idx++;
        p = son[p][u];
    }
    cnt[p] += 1;
}

int query(string& s)
{
    int p = 0;
    for (int i = 0; i < s.size(); i++)
    {
        int u = s[i] - 'a';
        if (!son[p][u]) return 0;
        p = son[p][u];
    }
    return cnt[p];
}


int main()
{
	int n;
	char op;
	string s;
	cin >> n;

	while (n--)
	{
		cin >> op >> s;
		if (op == 'I') insert(s);
		else cout << query(s) << endl;
	}

	return 0;
}

// *************************************************** //

#include <iostream>

using namespace std;

const int N = 100001;

int son[N][26], cnt[N], idx = 1;
char op[2], s[N];

void insert(char* s)
{
    int p = 0;
    for (int i = 0; s[i]; i++)
    {
        int u = s[i] - 'a';
        if (!son[p][u]) son[p][u] = idx++;
        p = son[p][u];
    }
    cnt[p] ++;
}

int query(char* s)
{
    int p = 0;
    for (int i = 0; s[i]; i++)
    {
        int u = s[i] - 'a';
        if (!son[p][u]) return 0;
        p = son[p][u];
    }
    
    return cnt[p];
}

int main()
{
    int n;
    scanf("%d", &n);
    
    while (n--)
    {
        scanf("%s%s", op, s);
        if (*op == 'I') insert(s);
        else printf("%d\n", query(s));
    }
    
    return 0;
}

Day 19 (2022.6.28)

#include <iostream>

using namespace std;

const int N = 1e5, M = 3e6;
int arr[N], son[M][2], idx = 0;

void insert(int x)
{
    int p = 0;
    for (int i = 30; i >= 0; i--)
    {
        int u = (x>>i) & 1;
        if (!son[p][u]) son[p][u] = ++idx;
        p = son[p][u];
    }
}

int query(int x)
{
    int res = 0, p = 0;
    for (int i = 30; i >= 0; i--)
    {
        int u = (x>>i) & 1;
        if (son[p][1-u])
        {
            res = res + (1<<i);
            p = son[p][1-u];
        }
        else
        {
            p = son[p][u];
        }
    }
    
    return res;
}

int main()
{
    int n;
    scanf("%d", &n);
    
    for (int i = 0; i < n; i++)
    {
        scanf("%d", &arr[i]);
        insert(arr[i]);
    }
    
    int res = 0;
    for (int i = 0; i < n; i++)
    {
        res = max(res, query(arr[i]));
    }
    
    printf("%d\n", res);
    
}

Day 20 (2022.6.29)

// AcWing 836. 合并集合

#include <iostream>

using namespace std;

const int N = 100010;

int n, m, p[N];

int find(int x)
{
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}

int main()
{
    scanf("%d%d",&n,&m);
    for (int i = 1; i <= n; i++) p[i] = i;
    
    char c[2];
    int a, b;
    while (m--)
    {
        scanf("%s%d%d", &c, &a, &b);
        if (*c == 'M') p[find(a)] = find(b);
        else
        {
            if (find(a) == find(b)) printf("%s\n", "Yes");
            else printf("%s\n", "No");
        }
    }
    return 0;
}

Day 21 (2022.7.2)

#include <iostream>
#include <string>
using namespace std;

const int N = 100010;

int p[N], cnt[N];

int find(int x)
{
    if (x != p[x]) p[x] = find(p[x]);
    return p[x];
}

int main()
{
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
    {
        p[i] = i, cnt[i] = 1;
    }
    
    char op[3];
    int a, b;
    
    while (m--)
    {
        scanf("%s", op);
        if (string(op) == "C")
        {
            scanf("%d%d", &a, &b);
            if (find(a) != find(b))
            {
                cnt[find(b)] = cnt[find(a)] + cnt[find(b)];
                p[find(a)] = find(b);
            }
        }
        else if (string(op) == "Q1")
        {
            scanf("%d%d", &a, &b);
            if (find(a) == find(b)) puts("Yes");
            else puts("No");
        }
        else
        {
            scanf("%d", &a);
            printf("%d\n", cnt[find(a)]);
        }
    }
    
    return 0;
}

Day 22 (2022.7.5)

#include <iostream>

using namespace std;

int const N = 500010;

int p[N], d[N], res;


int find(int x)
{
    if (p[x] != x)
    {
        int t = find(p[x]);
        d[x] += d[p[x]];
        p[x] = t;
    }
    
    return p[x];
}

int main()
{
    int n, k;
    scanf("%d%d", &n, &k);
    
    for (int i = 1; i <= n; i++) p[i] = i;
    
    int op, x, y;
    while (k--)
    {
        scanf("%d%d%d", &op, &x, &y);
        int px, py;
        px = find(x), py = find(y);
        
        if (x > n || y > n) res += 1;
        else if(op == 1)
        {
            if (px == py && (d[x] - d[y]) % 3) res += 1;
            else if(px != py)
            {
                p[px] = py;
                d[px] = d[y] - d[x];
            }
        }
        else
        {
            if (px == py && (d[x] - d[y] - 1) % 3) res += 1;
            else if(px != py)
            {
                p[px] = py;
                d[px] = d[y] - d[x] + 1;
            }
        }
    }
    
    printf("%d", res);
    
    return 0;
}

Day 23 (2022.7.6)

#include <iostream>

using namespace std;

const int N = 100010;

int h[N], n, m;

void down(int k)
{
    int u = k;
    if (2*k <= n && h[u]>h[2*k]) u = 2*k;
    if (2*k+1 <= n && h[u]>h[2*k+1]) u = 2*k+1;
    if (u != k)
    {
        swap(h[k], h[u]);
        down(u);
    }
}

int main()
{
    scanf("%d%d", &n, &m);
    
    for (int i = 1; i <= n; i++) scanf("%d", &h[i]);
    for (int i = n/2; i > 0; i--) down(i);
    
    while (m--)
    {
        printf("%d ", h[1]);
        h[1] = h[n--];
        down(1);
    }
    
    return 0;
}

Day 24 (2022.7.11)

// AcWing 839. 模拟堆
// 也可也 #include <cstring>, 用!strcmp(op, "I")

#include <iostream>

using namespace std;

const int N = 100010;
int h[N], hp[N], ph[N], index = 0, len = 0;

void swap_heap(int i, int j)
{
	swap(ph[hp[i]], ph[hp[j]]);
	swap(hp[i], hp[j]);
	swap(h[i], h[j]);
}

void down(int k)
{
	int u = k;
	if (2 * k <= len && h[2 * k] < h[u]) u = 2 * k;
	if (2 * k + 1 <= len && h[2 * k + 1] < h[u]) u = 2 * k + 1;
	if (u != k)
	{
		swap_heap(u, k);
		down(u);
	}
}

void up(int k)
{
	while (k / 2 && h[k / 2]>h[k])
	{
		swap_heap(k / 2, k);
		k /= 2;
	}
}

int main()
{
	
	int n, x, y;
	scanf("%d", &n);
    char op[4];
    
	while (n--)
	{
		scanf("%s", op);
		if (string(op) == "I")
		{
			scanf("%d", &x);
			len++, index++;
			ph[index] = len, hp[len] = index;
			h[len] = x;
			up(len);
		}
		else if (string(op) == "PM")
		{
			printf("%d\n", h[1]);
		}

		else if (string(op) == "DM")
		{
			swap_heap(1, len--);
			down(1);
		}
		else if (string(op) == "D")
		{
			scanf("%d", &x);
			x = ph[x];
			swap_heap(x, len--);
			up(x);
			down(x);
		}
		else
		{
			scanf("%d%d", &x, &y);
			x = ph[x];
			h[x] = y;
			up(x);
			down(x);
		}
	}

	std::cin.get();
	return 0;
}

Day 25 (2022.7.13)

// AcWing 840. 模拟散列表
// 拉链法

#include <iostream>
#include <cstring>

const int N = 100003;

int h[N], e[N], ne[N], idx = 0;

void insert(int x)
{
    int k = (x%N + N) % N;
    e[idx] = x, ne[idx] = h[k], h[k] = idx++;
}

void query(int x)
{
    int k = (x%N + N) % N;
    int index = h[k];
    while (index != -1)
    {
        if (e[index] == x)
        {
            puts("Yes");
            return;
        }
        index = ne[index];
    }
    puts("No");
}

int main()
{
    memset(h, 0xff, sizeof h);
    
    int n;
    scanf("%d", &n);
    
    char op[3];
    int x;
    while (n--)
    {
        scanf("%s", op);
        scanf("%d", &x);
        if (!strcmp(op, "I")) insert(x);
        else query(x);
    }
    
    return 0;
}

// 开放寻址法

#include <iostream>
#include <cstring>

const int N = 200003, null = 0x3f3f3f3f;
int h[N];

int find(int x)
{
    int k = (x%N + N) % N;
    while (h[k] != null && h[k]!=x)
    {
        if (++k == N) k = 0;
    }
    return k;
}

int main()
{
    memset(h, 0x3f, sizeof h);
    
    int n;
    scanf("%d", &n);
    
    char op[3];
    int x;
    while (n--)
    {
        scanf("%s%d", op, &x);
        // 这里由于I,Q只有一个字符,也可以用*op == 'I'
        if (!strcmp(op, "I")) h[find(x)] = x;
        else
        {
            if (h[find(x)] == null) puts("No");
            else puts("Yes");
        }
    }
    return 0;
}

Day 26 (2022.7.20)

AcWing 841. 字符串哈希

#include <iostream>

using namespace std;

const int N = 100010, P = 131;
unsigned long long h[N], p[N];
char str[N];

int get(int l, int r)
{
    return (h[r] - h[l - 1] * p[r - l + 1]) ;
}

int main()
{
    
    int n, m;
    scanf("%d%d", &n, &m);
    scanf("%s", str + 1);
    
    p[0] = 1;
    for (int i = 1; i <= n; i++)
    {
        h[i] = (h[i - 1] * P + str[i]);
        p[i] = (p[i - 1] * P);
    }
    
    while (m -- )
    {
        int l1, r1, l2, r2;
        scanf("%d%d%d%d", &l1, &r1, &l2, &r2);

        if (get(l1, r1) == get(l2, r2)) puts("Yes");
        else puts("No");
    }

    return 0;
    
    
}

Day 27 (2022.7.23)

// AcWing 842. 排列数字

#include <iostream>

using namespace std;

int n, st[7], path[7];


void dfs(int k)
{
    if (k == n)
    {
        for (int i = 0; i < n; i++) printf("%d ", path[i]);
        printf("\n");
    }
    
    for (int i = 1; i <= n; i++)
    {
        if (!st[i])
        {
            path[k] = i;
            st[i] = 1;
            dfs(k+1);
            st[i] = 0;
        }
    }
}

int main()
{
    scanf("%d", &n);
    
    dfs(0);
    return 0;
}

Day 28 (2022.7.24)

// AcWing 843. n-皇后问题

#include <iostream>

using namespace std;

const int N = 10;

int n, col[N], dg[2*N], bdg[2*N];
char grid[N][N];

void dfs(int r)
{
	if (r == n)
	{
		for (int i = 0; i < n; i++)
			puts(grid[i]);
		puts("");
		return;
	}

	for (int c = 0; c < n; c++)
	{
		if (!col[c] && !dg[n + r - c] && !bdg[r + c])
		{
			col[c] = 1, dg[n + r - c] = 1, bdg[r + c] = 1;
			grid[r][c] = 'Q';
			dfs(r + 1);
			grid[r][c] = '.';
			col[c] = 0, dg[n + r - c] = 0, bdg[r + c] = 0;
		}
	}
}

int main()
{
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		for (int c = 0; c < n; c++)
		{
			grid[i][c] = '.';
		}
	}
	dfs(0);
	return 0;
}
// AcWing 844. 走迷宫

#include <iostream>
#include <cstring>
#include <queue>

using namespace std;

typedef pair<int, int> PII;

const int N = 101;

int grid[N][N], d[N][N], n, m;

void bfs()
{
    queue<PII> q;
    
    memset(d, 0xff, sizeof d);
    d[0][0] = 0;
    q.push({0, 0});
    
    int dx[4] = { -1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
    
    while (q.size())
    {
        PII t = q.front();
        q.pop();
        
        for (int i = 0; i < 4; i++)
        {
            int x = t.first + dx[i], y = t.second + dy[i];
            if (x>=0 && x<n && y>=0 && y<m && grid[x][y] ==0 && d[x][y]==-1)
            {
                d[x][y] = d[t.first][t.second] + 1;
                q.push({x, y});
                if (x == n-1 && y == m-1)
                {
                    printf("%d", d[n-1][m-1]);
                    break;
                }
            }
        }
    }
    
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            scanf("%d", &grid[i][j]);
            
    bfs();
    return 0;
}
// AcWing 845. 八数码

#include <string>
#include <iostream>
#include <unordered_map>
#include <algorithm>
#include <queue>

using namespace std;

int bfs(string state)
{
    string end = "12345678x";
    int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
    
    queue<string> q;
    unordered_map<string, int> d;
    
    q.push(state);
    d[state] = 0;
    
    while (q.size())
    {
        string t = q.front();
        q.pop();
        
        if (t == end) return d[t];
        
        int dist = d[t], k = t.find('x');
        int x = k/3, y = k%3;
        
        for (int i = 0; i < 4; i++)
        {
            int nx = x + dx[i], ny = y + dy[i];
            if (nx>=0 && nx<3 && ny>=0 && ny<3)
            {
                swap(t[nx*3 + ny], t[k]);
                if (!d.count(t))
                {
                    d[t] = dist + 1;
                    q.push(t);
                }
                swap(t[nx*3 + ny], t[k]);
            }
        }
    }
    
    return -1;
}

int main()
{
    char c;
    string state;
    for (int i = 0; i < 9; i++)
    {
        cin >> c;
        state += c;
    }
    
    cout << bfs(state) << endl;
    return 0;
}

Day 29 (2022.7.26)

AcWing 846. 树的重心

#include <iostream>
#include <cstring>

using namespace std;

const int N = 100010;

int h[N], e[2*N], ne[2*N], st[N], idx = 0, ans = N, n;

void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

int dfs(int u)
{
    st[u] = 1;
    int sum = 1, res = 0;
    
    int i = h[u];
    while (i != -1)
    {
        int j = e[i];
        if (!st[j])
        {
            int s = dfs(j);
            res = max(res, s);
            sum += s;
        }
        i = ne[i];
    }
    
    res = max(res, n - sum);
    ans = min(ans, res);
    return sum;
}

int main()
{
    memset(h, -1, sizeof h);
    scanf("%d", &n);
    
    int a, b;
    for (int i = 0; i < n-1; i++)
    {
        scanf("%d%d", &a, &b);
        add(a, b);
        add(b, a);
    }
    
    dfs(1);
    printf("%d", ans);
    
}

Day 30 (2022.7.27)

#include <iostream>
#include <queue>
#include <cstring>

using namespace std;

const int N = 100010;
int h[N], e[N], ne[N], idx = 0, n, m, dist[N];


void add(int a, int b)
{
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

int bfs()
{
    queue<int> q;
    q.push(1);
    dist[1] = 0;
    
    while (q.size())
    {
        int t = q.front();
        q.pop();
        
        int i = h[t];
        while ( i!=-1 )
        {
            int b = e[i];
            
            if (dist[b] == -1)
            {
                q.push(b);
                dist[b] = dist[t] + 1;
            }
                
            i = ne[i];
        }
    }
    
    return dist[n];
}

int main()
{
    memset(h, -1, sizeof h);
    memset(dist, -1, sizeof dist);
    
    scanf("%d%d", &n, &m);
    int a, b;
    for (int i = 0; i < m; i++)
    {
        scanf("%d%d", &a, &b);
        add(a, b);
    }
    
    cout << bfs() << endl;
    
    return 0;
}

······

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值