0
点赞
收藏
分享

微信扫一扫

天梯赛题目集整理

萍儿的小确幸 2022-04-21 阅读 29
算法

PTA 天梯赛题目整理

并查集板子

(1)朴素并查集:
    int p[N]; //存储每个点的祖宗节点
    // 返回x的祖宗节点
    int find(int x)
    {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }
    // 初始化,假定节点编号是1~n
    for (int i = 1; i <= n; i ++ ) p[i] = i;
    // 合并a和b所在的两个集合:
    p[find(a)] = find(b);

(2)维护size的并查集:
    int p[N], size[N];
    //p[]存储每个点的祖宗节点, size[]只有祖宗节点的有意义,表示祖宗节点所在集合中的点的数量
    // 返回x的祖宗节点
    int find(int x)
    {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
    }

    // 初始化,假定节点编号是1~n
    for (int i = 1; i <= n; i ++ )
    {
        p[i] = i;
        size[i] = 1;
    }

    // 合并a和b所在的两个集合:
    size[find(b)] += size[find(a)];
    p[find(a)] = find(b);


(3)维护到祖宗节点距离的并查集:

    int p[N], d[N];
    //p[]存储每个点的祖宗节点, d[x]存储x到p[x]的距离

    // 返回x的祖宗节点
    int find(int x)
    {
        if (p[x] != x)
        {
            int u = find(p[x]);
            d[x] += d[p[x]];
            p[x] = u;
        }
        return p[x];
    }

    // 初始化,假定节点编号是1~n
    for (int i = 1; i <= n; i ++ )
    {
        p[i] = i;
        d[i] = 0;
    }

    // 合并a和b所在的两个集合:
    p[find(a)] = find(b);
    d[find(a)] = distance; // 根据具体问题,初始化find(a)的偏移量

L2

难点

18(多项式) 28/34(大模拟)

L2-001 紧急救援

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std ;
const int N = 510 ;
int n, m, s, d, dist[N], g[N][N], num[N], r[N], rescure[N], pre[N] ;
// num表示到当前结点的路径数量 
// r表示到当前结点的救援队数量  rescue表示当前结点的救援队数量 
// pre表示走到当前结点的上一个结点
bool st[N] ;

void print_path(int i) // 递归打印
{
    if (i == s)
    {
        printf("%d", i) ;
        return ;
    }
    print_path(pre[i]) ;
    printf(" %d", i) ;
}

void dijkstra()
{
    memset(dist, 0x3f, sizeof dist) ;
    dist[s] = 0 ;
    num[s] = 1 ;
    r[s] = rescure[s] ;
    for (int i = 0;i < n;i ++ )
    {
        int t = -1 ;
        for (int j = 0;j < n;j ++ )
        {
            if (!st[j] && (t == -1 || dist[t] > dist[j]))
            {
                t = j ;
            }
        }
        st[t] = true ;
        for (int j = 0;j < n;j ++ )
        {
            if (dist[j] > dist[t] + g[t][j])
            {
                dist[j] = dist[t] + g[t][j] ;
                num[j] = num[t] ;
                r[j] = r[t] + rescure[j] ;
                pre[j] = t ;
            }
            else if (dist[j] == dist[t] + g[t][j])
            {
                num[j] = num[t] + num[j] ;
                if (r[j] < r[t] + rescure[j])
                {
                    r[j] = r[t] + rescure[j] ;
                    pre[j] = t ;
                }
            }
        }
    }
}

int main()
{
    cin >> n >> m >> s >> d ;
    for (int i = 0;i < n;i ++ ) cin >> rescure[i] ;
    memset(g, 0x3f, sizeof g) ;
    for (int i = 0;i < m;i ++ )
    {
        int a, b, c; cin >> a >> b >> c;
        g[a][b] = g[b][a] = c;
    }

    dijkstra() ;

    printf("%d %d\n", num[d], r[d]);
    print_path(d) ;


    return 0 ;
}

L2-002 链表去重

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>

using namespace std;
const int N = 100010;
bool st[N];
struct node {
    int addr, key, next, idx;
}nodes[N];

bool cmp(node a, node b) {
    return a.idx < b.idx;
}

int main()
{
    int h, n, x;
    int cnt1 = 0, cnt2 = 0;
    scanf("%d%d", &h, &n);

    for (int i = 0; i < N; i ++ ) nodes[i].idx = 2 * N;

    for (int i = 0; i < n; i ++ )
    {
        scanf("%d", &x);
        nodes[x].addr = x;
        scanf("%d%d", &nodes[x].key, &nodes[x].next);
    }

    for (int i = h; i != -1; i = nodes[i].next)
    {
        if (!st[abs(nodes[i].key)])
        {
            st[abs(nodes[i].key)] = true;
            nodes[i].idx = cnt1 ++ ;
        }
        else
        {
            nodes[i].idx = N + cnt2;
            cnt2 ++ ;
        }
    }

    sort(nodes, nodes + N, cmp);
    int cnt = cnt1 + cnt2;

    for (int i = 0; i < cnt; i ++ )
    {
        if (i != cnt1 - 1 && i != cnt - 1)
        {
            printf("%05d %d %05d\n", nodes[i].addr, nodes[i].key, nodes[i+1].addr);
        }
        else
        {
            printf("%05d %d -1\n", nodes[i].addr, nodes[i].key);
        }
    }

    return 0;
}

L2-003 月饼

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;
const int N = 1010;
struct node
{
    double num, price, weight;
}nodes[N];

bool cmp(node a, node b)
{
    return a.weight > b.weight;
}

int main()
{
    int n, need;
    cin >> n >> need;
    for (int i = 0; i < n; i ++ ) cin >> nodes[i].num;
    for (int i = 0; i < n; i ++ ) cin >> nodes[i].price;
    for (int i = 0; i < n; i ++ ) nodes[i].weight = nodes[i].price / nodes[i].num;
    sort(nodes, nodes + n, cmp);
    double res = 0;

    for (int i = 0; i < n; i ++ )
    {
        if (nodes[i].num <= need)
        {
            res += nodes[i].price;
        }
        else
        {
            res += nodes[i].weight * need;
            break;
        }
        need -= nodes[i].num;
    }

    printf("%.2lf\n", res);

    return 0;
}

L2-004 这是二叉搜索树吗

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 1010;
bool isMirror;
int pre[N], post[N], idx;

// get BST's sequence of post-order
void getpost(int root, int tail)
{
    if (root > tail) return;
    int i = root + 1, j = tail;
    if (!isMirror)
    {
        // 找到右子树的根节点
        while (i <= tail && pre[root] > pre[i]) i ++ ;
        // 找到左子树的最后一个结点
        while (j > root && pre[root] <= pre[j]) j -- ;
    }
    else
    {
        // 镜像
        // 找到右子树的根节点
        while (i <= tail && pre[root] <= pre[i]) i ++ ;
        // 找到左子树的最后一个结点
        while (j > root && pre[root] > pre[j]) j -- ;
    }

    // 判断是否到了根节点, 不判断也可以
    // if (i - j != 1) return;
    // 递归左子树
    getpost(root + 1, j);
    // 递归右子树
    getpost(i, tail);
    // 后序遍历结点
    post[idx ++ ] = pre[root];
}

int main()
{
    int n; cin >> n;
    for (int i = 0; i < n; i ++ ) cin >> pre[i];

    getpost(0, n - 1);
    if (idx != n)
    {
        isMirror = true;
        idx = 0;
        getpost(0, n - 1);
    }

    if (idx == n)
    {
        // 注意输入格式, 不能有多余空格
        cout << "YES" << endl << post[0];
        for (int i = 1; i < idx; i ++ ) cout << " " <<  post[i];
    }
    else
    {
        cout << "NO" << endl;
    }

    return 0;
}

L2-005 集合相似度

#include <iostream>
#include <cstdio>
#include <set>

using namespace std;
const int N = 100;
set<int> s[N];

int main()
{
    int n, m, k, x, a, b;
    cin >> n;
    for (int i = 0; i < n; i ++ )
    {
        cin >> m;
        for (int j = 0; j < m; j ++ )
        {
            cin >> x;
            s[i].insert(x);
        }
    }

    cin >> k;
    for (int i = 0; i < k; i ++ )
    {
        cin >> a >> b;
        int nc = 0, nt = s[b - 1].size();
        for (auto it = s[a - 1].begin(); it != s[a - 1].end(); it ++ )
        {
            if (s[b - 1].find(*it) == s[b - 1].end())
                nt ++ ;
            else
                nc ++ ;
        }
        double ans = (double)nc / nt * 100;
        printf("%.2lf%%\n", ans);
    }

    return 0;
}

L2-006 树的遍历

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>

using namespace std;
const int N = 50;
int n, post[N], in[N];
map<int, int> level;

void pre(int rt, int st, int ed, int idx)
{
    if (st > ed) return;
    int i = st;
    while (i < ed && in[i] != post[rt]) i ++ ; // 找到当前子树根节点在中序遍历中的位置

    // 先序遍历处理代码
    level[idx] = post[rt];
    pre(rt - 1 - ed + i, st, i - 1, 2 * idx + 1); // idx为子树的根结点在层序遍历中的位置
    pre(rt - 1, i + 1, ed, 2 * idx + 2);
}

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++ ) cin >> post[i];
    for (int i = 0; i < n; i ++ ) cin >> in[i];
    pre(n-1, 0, n-1, 0);
    auto it = level.begin();
    printf("%d", it->second);
    while (++it != level.end()) printf(" %d", it->second);

    return 0;
}

L2-007 家庭房产

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 1010;
struct DATA{
	int id, fid, mid, num, area;
	int cid[10];
} datas[N];

struct node{
	int id, people;
	double num, area;
	bool flag = false;
}ans[N * 10];

int p[N*10];
bool vis[N*10];

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

void Union(int a, int b)
{
	a = find(a);
	b = find(b);
	if (a > b) swap(a, b);
	p[b] = p[a];
}

int cmp(node a, node b)
{
	if (a.area != b.area)
		return a.area > b.area;
	else
		return a.id < b.id;
}

int main()
{
	int n, k, cnt = 0;
	cin >> n;
	for (int i = 0; i < N * 10; i ++ ) p[i] = i;
	for (int i = 0; i < n; i ++ )
	{
		cin >> datas[i].id >> datas[i].fid >> datas[i].mid >> k;
		vis[datas[i].id] = true;
		if (datas[i].fid != -1) {
			vis[datas[i].fid] = true;
			Union(datas[i].id, datas[i].fid);
		}
		if (datas[i].mid != -1) {
			vis[datas[i].mid] = true;
			Union(datas[i].id, datas[i].mid);
		}
		for (int j = 0; j < k; j ++ )
		{
			cin >> datas[i].cid[j];
			vis[datas[i].cid[j]] = true;
			Union(datas[i].cid[j], datas[i].id);
		}
		cin >> datas[i].num >> datas[i].area;
	}
	
	for (int i = 0; i < n; i ++ )
	{
		int id = find(datas[i].id);
		ans[id].id = id;
		ans[id].num += datas[i].num;
		ans[id].area += datas[i].area;
		ans[id].flag = true;
	}
	
	for (int i = 0; i < N * 10; i ++ )
	{
		if (vis[i])
			ans[find(i)].people ++ ; 
		if (ans[i].flag)
			cnt ++ ; 
	}
	
	for (int i = 0; i < N * 10; i ++ )
	{
		if (ans[i].flag)
		{
			ans[i].num = (double)(ans[i].num * 1.0 / ans[i].people);
			ans[i].area = (double)(ans[i].area * 1.0 / ans[i].people);
		}
	}
	
	sort(ans, ans + N * 10, cmp);
	cout << cnt << endl;
	for (int i = 0; i < cnt; i ++ )
		printf("%04d %d %.3lf %.3lf\n", ans[i].id, ans[i].people, ans[i].num, ans[i].area);
	
	return 0;
}

L2-008 最长对称子串

#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>

using namespace std;
const int N = 1010;

int main()
{
    string s;
    getline(cin, s);
    int res = -1, temp = 0;
    for (int i = 0; i < s.size(); i ++ )
    {
        // 奇数情况
        temp = 1;
        for (int j = 1; j < s.size(); j ++ )
        {
            if (i - j < 0 || i + j >= s.size() || s[i - j] != s[i + j]) break;
            temp += 2;
        }
        res = max(res, temp);

        // 偶数情况
        temp = 0;
        for (int j = 1; j < s.size(); j ++ )
        {
            if (i - j + 1 < 0 || i + j >= s.size() || s[i - j + 1] != s[i + j]) break;
            temp += 2;
        }
        res = max(res, temp);
    }

    cout << res << endl;

    return 0;
}

L2-009 抢红包

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 10010;

struct node {
    int id, tot, num;
}nodes[N];

bool cmp(node a, node b)
{
    if (a.tot != b.tot)
        return a.tot > b.tot;
    else if (a.num != b.num)
        return a.num > b.num;
    else
        return a.id < b.id;
}

int main()
{
    int n, k, id, val;
    cin >> n;
    for (int i = 1; i <= n; i ++ )
    {
        cin >> k;
        nodes[i].id = i;
        for (int j = 0; j < k; j ++ )
        {
            cin >> id >> val;
            nodes[id].tot += val;
            nodes[i].tot -= val;
            nodes[id].num ++ ;
        }
    }

    sort(nodes + 1, nodes + n + 1, cmp);
    for (int i = 1; i <= n; i ++ )
    {
        double t = (double)(nodes[i].tot * 1.00 / 100);
        printf("%d %.2lf\n", nodes[i].id, t);
    }

    return 0;
}

L2-010 排座位

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 110;
int p[N], rival[N][N];

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

void _union(int a, int b)
{
    a = find(a);
    b = find(b);
    p[a] = p[b];
}

int main()
{
    int n, m, k, a, b, c;
    cin >> n >> m >> k;

    for (int i = 1; i <= n; i ++ ) p[i] = i;
    for (int i = 0; i < m; i ++ )
    {
        cin >> a >> b >> c;
        if (c == 1) _union(a, b);
        else {
            rival[a][b] = 1;
            rival[b][a] = 1;
        }
    }

    for (int i = 0; i < k; i ++ )
    {
        cin >> a >> b;
        if (find(a) == find(b) && rival[a][b] == 0)
            puts("No problem");
        else if (find(a) == find(b) && rival[a][b] == 1)
            puts("OK but...");
        else if (find(a) != find(b) && rival[a][b] == 0)
            puts("OK");
        else if (find(a) != find(b) && rival[a][b] == 1)
            puts("No way");
    }

    return 0;
}

L2-011 玩转二叉树

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>

using namespace std;
const int N = 50;
int pre[N], in[N];
map<int, int> lev;

void level(int rt, int st, int ed, int idx)
{
    if (st > ed) return;
    int i = st;
    while (i < ed && in[i] != pre[rt]) i ++ ; // 确定当前子树的根节点
    lev[idx] = pre[rt];
    level(rt + 1, st, i - 1, idx * 2 + 2);
    level(rt + i - st + 1, i + 1, ed, idx * 2 + 1);
}

int main()
{
    int n; cin >> n;
    for (int i = 0; i < n; i ++ ) cin >> in[i];
    for (int i = 0; i < n; i ++ ) cin >> pre[i];

    level(0, 0, n-1, 0);
    auto it = lev.begin();
    cout << it->second;
    while (++it != lev.end())
    {
        printf(" %d", it->second);
    }

    return 0;
}

L2-012 关于堆的判断

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>

using namespace std;
const int N = 1010;
int n, m, h[N];
map<int, int> mp;

void up(int x)
{
	while (x/2 && h[x/2] > h[x])
	{
		swap(h[x/2], h[x]);
		x >>= 1;
	}
}

int main()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i ++ )
	{
		cin >> h[i];
		up(i);
	}
	
	for (int i = 1; i <= n; i ++ ) mp[h[i]] = i;
	
	string s;
	int x, y;
	for (int i = 0; i < m; i ++ )
	{
		cin >> x >> s;
		if (s[0] == 'a')
		{
			cin >> y;
			getline(cin, s);
			if (mp[x]/2 == mp[y]/2) cout << 'T' << endl;
			else cout << 'F' << endl;
		} else {
			cin >> s;
			cin >> s;
			if (s[0] == 'r') {
				if (mp[x] == 1) cout << 'T' << endl;
				else cout << 'F' << endl;
			} else if (s[0] == 'p') {
				cin >> s;
				cin >> y;
				if (mp[y]/2 == mp[x]) cout << 'T' << endl;
				else cout << 'F' << endl;
			} else {
				cin >> s;
				cin >> y;
				if (mp[x]/2 == mp[y]) cout << 'T' << endl;
				else cout << 'F' << endl;
			}
		}
	}
	
	return 0;
}

L2-013 红色警报

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 510;
bool st[N];
int g[N][N], n, m, k;

void dfs(int x)
{
    st[x] = true;
    for (int i = 0; i < n; i ++ ) 
        if (!st[i] && g[x][i] == 1) 
            dfs(i);
}

int calc_cnt()
{
    int cnt = 0;
    memset(st, false, sizeof st);
    for (int i = 0; i < n; i ++ ) 
        if (!st[i]) 
        {
            dfs(i);
            cnt ++ ; 
        }
        
    return cnt;
}

int main() 
{
    cin >> n >> m;
    int a, b, c;
    for (int i = 0; i < m; i ++ ) 
    {
        cin >> a >> b;
        g[a][b] = g[b][a] = 1;
    }
    int cnt = calc_cnt();
    
    cin >> k;
    for (int i = 0; i < k; i ++ ) 
    {
        cin >> c;
        for (int j = 0; j < n; j ++ ) 
        {
            g[c][j] = g[j][c] = 0;
        }
        int t_cnt = calc_cnt();
        if (t_cnt > cnt + 1) 
            printf("Red Alert: City %d is lost!\n", c);
        else 
            printf("City %d is lost.\n", c);
        
        cnt = t_cnt;
        if (i == n - 1) 
            printf("Game Over.\n");
    }
    
    return 0;
}

L2-014 列车调度

#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>

using namespace std;
const int N = 10010;
set<int> s;
int n, t;

int main()
{
    cin >> n;
    s.insert(0);
    // set自动排序
    for (int i = 0; i < n; i ++ )
    {
        cin >> t;
        if (t < *s.rbegin()) // end指向最后一个元素的后一个, rbegin指向最后一个元素
        {
            s.erase(*(s.upper_bound(t)));
        }
        s.insert(t);
    }

    cout << s.size() - 1 << endl;

    return 0;
}

L2-015 互评成绩

#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>

using namespace std;
const int N = 10010;
double stu[N], grade[20];

int main()
{
    int n, k, m; cin >> n >> k >> m;
    for (int i = 0; i < n; i ++ ) 
    {
        double mmax = -1, mmin = 110, sum = 0;
        for (int j = 0; j < k; j ++ ) 
        {
            cin >> grade[j];
            sum += grade[j];
            mmax = max(mmax, grade[j]);
            mmin = min(mmin, grade[j]);
        }
        stu[i] = (sum - mmax - mmin) / (k - 2);
    }
    
    sort(stu, stu + n);
    for (int i = n - m; i < n; i ++ ) 
    {
        if (i == n - 1) printf("%.3lf\n", stu[i]);
        else printf("%.3lf ", stu[i]);
    }

    return 0;
}

L2-016 愿天下有情人都是失散多年的兄妹

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
const int N = 100010;
int n, k;
char gender[N];
bool st[N], flag;
vector<int> g[N];

void dfs(int u, int d)
{
    if (d == 5) return;
    if (st[u]) 
    {
        flag = true;
        return;
    }
    st[u] = true;
    for (int i = 0; i < g[u].size(); i ++ ) 
        dfs(g[u][i], d + 1);
}

int main()
{
    int x, f, m;
    cin >> n;
    for (int i = 0; i < n; i ++ ) 
    {
        cin >> x;
        cin >> gender[x] >> f >> m;
        if (f != -1) gender[f] = 'M', g[x].push_back(f);
        if (m != -1) gender[m] = 'F', g[x].push_back(m);
    }
    
    cin >> k;
    int a, b;
    for (int i = 0; i < k; i ++ ) 
    {
        cin >> a >> b;
        if (gender[a] == gender[b])
        {
            cout << "Never Mind" << endl;
            continue;
        }
        memset(st, false, sizeof st);
        flag = false;
        dfs(a, 0);
        dfs(b, 0);
        if (flag) 
            cout << "No" << endl;
        else 
            cout << "Yes" << endl;
    }

    return 0;
}

L2-017 人以群分

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
typedef long long LL;
const int N = 100010;
LL p[N];

int main()
{
    int n; cin >> n;
    for (int i = 0; i < n; i ++ ) cin >> p[i];
    sort(p, p + n);
    
    LL res = 0;
    for (int i = 0; i < n; i ++ ) 
    {
        if (i <= n / 2 - 1) res -= p[i];
        else res += p[i];
    }
    
    cout << "Outgoing #: " << n / 2 + (n & 1) << endl ;
    cout << "Introverted #: " << n / 2 << endl ;
    cout << "Diff = " << res << endl ;

    return 0;
}

L2-018 多项式A除以B


L2-019 悄悄关注

#include <iostream>
#include <cstring>
#include <algorithm>
#include <string>
#include <map>

using namespace std;
const int N = 10010;
map<string, bool> st;
map<string, int> mp;

int main()
{
    int n, m, cnt, avg = 0;
    string s;
    cin >> n;
    for (int i = 0; i < n; i ++ )
    {
        cin >> s;
        st[s] = true;
    }

    cin >> m;

    for (int i = 0; i < m; i ++ )
    {
        cin >> s >> cnt;
        mp[s] = cnt;
        avg += cnt;
    }

    avg /= m;
    bool flag = false;
    for (auto it : mp)
    {
        if (it.second > avg && !st[it.first])
        {
            cout << it.first << endl;
            flag = true;
        }
    }

    if (!flag) cout << "Bing Mei You" << endl;

    return 0;
}

L2-020 功夫传人

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
const int N = 100010;
vector<vector<int> > v;
int n, k;
double z, r, res = 0;
bool st[N];

void dfs(int idx, double p) 
{
    if (st[idx]) 
    {
        res += p * v[idx][0];
        return;
    }
    
    for (int i = 0; i < v[idx].size(); i ++ ) 
        dfs(v[idx][i], p * (1 - r / 100));
}

int main()
{
    cin >> n >> z >> r;
    v.resize(n);
    int t;
    for (int i = 0; i < n; i ++ ) 
    {
        cin >> k;
        if (k == 0) 
        {
            cin >> t;
            v[i].push_back(t);
            st[i] = true;
        }
        for (int j = 0; j < k; j ++ ) 
        {
            cin >> t;
            v[i].push_back(t);
        }
    }
    dfs(0, z);
    cout << (int)res << endl;

    return 0;
}

L2-021 点赞狂魔

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
const int N = 1e7 + 10;
bool st[N];
struct usr {
    string name;
    int sum, cnt;
};

bool cmp(usr a, usr b) 
{
    if (a.cnt != b.cnt) return a.cnt > b.cnt;
    return 1.0 * a.sum / a.cnt < 1.0 * b.sum / b.cnt;
}

int main()
{
    int n; cin >> n;
    vector<usr> v(n);
    for (int i = 0; i < n; i ++ ) 
    {
        memset(st, false, sizeof st);
        int k, t, cnt = 0;
        string name;
        cin >> name >> k;
        for (int j = 0; j < k; j ++ ) 
        {
            cin >> t;
            if (!st[t])
            {
                st[t] = true;
                cnt ++ ; 
            }
        }
        v[i] = {name, k, cnt};
    }
    
    int minv = min(n, 3);
    partial_sort(v.begin(), v.begin() + minv, v.end(), cmp);
    for (int i = 0; i < minv; i ++ ) 
    {
        if (i != 0) cout << " ";
        cout << v[i].name;
    }
    
    for (int i = 0; i < 3 - minv; i ++ ) 
        cout << " -";
    cout << endl;
    
    return 0;
}

L2-022 重排链表

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
const int N = 100010;
struct node {
    int id, data, next;
}nodes[N];

int main()
{
    int h, n;
    cin >> h >> n;
    vector<node> v, ans;
    for (int i = 0; i < n; i ++ )
    {
        int tid, tdata, tnext;
        cin >> tid >> tdata >> tnext;
        nodes[tid] = {tid, tdata, tnext};
    }

    while (h != -1)
    {
        v.push_back(nodes[h]);
        h = nodes[h].next;
    }

    int l = 0, r = v.size() - 1;
    while (1)
    {
        ans.push_back(v[r]);
        r -- ;
        if (r - l == -1) break;
        ans.push_back(v[l]);
        l ++ ;
        if (r - l == -1) break;
    }

    for (int i = 0; i < ans.size(); i ++ )
    {
        if (i != ans.size() - 1)
            printf("%05d %d %05d\n", ans[i].id, ans[i].data, ans[i+1].id);
        else
            printf("%05d %d -1\n", ans[i].id, ans[i].data);
    }

    return 0;
}

L2-023 图着色问题

#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <set>

using namespace std ;
const int N = 510 ; int n, m, k ;
vector<vector<int>> v(N) ; // 用 vector 作邻接表来存边
int color[N] ; // 记录 每个点的 color

bool check(int i) // 检查每个点的 color 是否与其邻边不一样
{
    for (int j = 0;j < v[i].size();j ++ )
    {
        if (color[i] == color[v[i][j]]) return false ;
    }
    return true ;
}

int main()
{
    cin >> n >> m >> k ;
    for (int i = 0;i < m;i ++ )
    {
        int a, b; cin >> a >> b;
        v[a].push_back(b) ;
        v[b].push_back(a) ;
    }

    int t ; cin >> t ;
    while (t -- )
    {
        bool flag = true ; set<int> s ; // set 存储当前图的颜色种数 去重
        for (int i = 1;i <= n;i ++ )
        {
            cin >> color[i] ;
            s.insert(color[i]) ;
        }
        if (s.size() != k)
        {
            cout << "No" << endl ;
            flag = false ;
        }
        else
        {
            for (int i = 1;i <= n;i ++ )
            {
                if (!check(i))
                {
                    cout << "No" << endl ;
                    flag = false ;
                    break ;
                }
            }
        }
        if (flag) cout << "Yes" << endl ;
    }

    return 0 ;
}

L2-024 部落

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 10010;
int p[N];

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

int main()
{
    int n, k, t, x; cin >> n;
    int mmax = -1;
    for (int i = 1; i <= N - 10; i ++ ) p[i] = i;
    for (int i = 0; i < n; i ++ )
    {
        cin >> k;
        cin >> t;
        mmax = max(mmax, t);
        for (int j = 1; j <= k - 1; j ++ )
        {
            cin >> x;
            mmax = max(mmax, x);
            int a = find(x), b = find(t);
            if (a != b) p[a] = p[b];
        }
    }

    int cnt = 0;
    for (int i = 1; i <= mmax; i ++ )
        if (i == find(i)) cnt ++ ;

    cout << mmax << " " << cnt << endl;
    int q; cin >> q;
    while (q -- )
    {
        int a, b; cin >> a >> b;
        if (find(a) != find(b)) cout << "N" << endl;
        else cout << "Y" << endl;
    }

    return 0;
}

L2-025 分而治之

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
const int N = 10010;
int n, m, k, aa[N], a[N];

void check()
{
    for (int i = 1; i <= n; i ++ ) 
    {
        if (a[i] > 0) 
        {
            cout << "NO" << endl;
            return;
        }
    }
    cout << "YES" << endl;
    return;
}

int main()
{
    cin >> n >> m;
    vector<vector<int> > v(n + 1);
    while (m -- ) 
    {
        int c1, c2;
        cin >> c1 >> c2;
        aa[c1] ++ ; 
        aa[c2] ++ ; 
        v[c1].push_back(c2);
        v[c2].push_back(c1);
    }
    
    cin >> k;
    while (k -- ) 
    {
        int cnt, num;
        cin >> cnt;
        for (int i = 1; i <= n; i ++ ) a[i] = aa[i];
        
        for (int i = 0; i < cnt; i ++ ) 
        {
            cin >> num;
            a[num] = 0;
            for (int j = 0; j < v[num].size(); j ++ ) 
                a[v[num][j]] -- ;
        }
        check();
    }
    
    return 0;
}

L2-026 小字辈

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
const int N = 100010;
vector<int>v[N];
int n ,a[N] ,depth[N] ,flag;
int bfs() {
    queue<int>q;
    q.push(v[0][0]);//根节点只有一个孩子,直接把这个孩子传入队列
    int x;
    while (!q.empty()) {
        x = q.front();
        q.pop();
        for (int i = 0; i < v[x].size(); i++) {//搜索所有的孩子
            depth[v[x][i]] = depth[x] + 1;//深度为父节点+1
            q.push(v[x][i]);
        }
    }
    return depth[x];//返回树的深度
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        if (a[i] == -1) {//将根节点改为0
            a[i] = 0;
            depth[i] = 1;//根节点的深度为1
        }
        v[a[i]].push_back(i);//i是a[i]的孩子
    }
    int ans = bfs();
    cout << ans << endl;
    // 按顺序遍历
    for (int i = 1; i <= n; i++) {//遍历找出距离根节点最远的叶节点
        if (depth[i] == ans) {
            if(flag) cout << ' ';
            cout << i ,flag = 1;
        }
    }
    cout << endl;
    return 0;
}

L2-027 名人堂与代金券

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
const int N = 10010;
struct stu {
    string name;
    int score;
};
int rk[N];

bool cmp(stu a, stu b)
{
    if (a.score != b.score) return a.score > b.score;
    return a.name < b.name;
}

int main()
{
    int n, g, k, sum = 0;
    cin >> n >> g >> k;
    vector<stu> v(n);
    for (int i = 0; i < n; i ++ )
    {
        cin >> v[i].name >> v[i].score;
        if (v[i].score >= 60) sum += 20;
        if (v[i].score >= g) sum += 30;
    }
    sort(v.begin(), v.end(), cmp);
    rk[0] = 1;
    for (int i = 1; i < n; i ++ )
    {
        if (v[i].score == v[i-1].score)
            rk[i] = rk[i-1];
        else
            rk[i] = i + 1;
    }
    cout << sum << endl;
    for (int i = 0; rk[i] <= k && i < n; i ++ )
        cout << rk[i] << " " << v[i].name << " " << v[i].score << endl;

    return 0;
}

L2-028 秀恩爱分得快

#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp (int a, int b) {
    if(abs(a) == 1000) return true;
    if(abs(b) == 1000) return false;
    return abs(a) < abs(b);
}

int main(){
    int n, m, num, k, sex[1010] = {0}, love[3] ;
    double sum[1010] = {0}, maxn[3] = {0} ;
    string s ;
    cin >> n >> m ;
    vector<vector<int>> v(m), ans(3);
    for(int i = 0; i < m; i++) {
        cin >> k;
        for(int j = 0; j < k; j++){
            cin >> s;
            if(s == "0")  s = "1000";
            if(s == "-0") s = "-1000";
            num = stoi(s); // 字符串转换函数
            sex[abs(num)] = num;
            v[i].push_back(num);
        }
    }
    for(int i = 1; i <= 2; i++) {
        cin >> s;
        if(s == "0")  s = "1000";
        if(s == "-0") s = "-1000";
        love[i] = stoi(s);
    }
    for(int k = 1; k <= 2; k++) {
        for(int i = 0; i < m; i++) {
            int flag = 0;
            for(int j = 0; j < v[i].size(); j++){
                if(v[i][j] == love[k]) {
                    flag = 1;
                    break;
                }
            }
            if(flag == 1) {
                for(int j = 0; j < v[i].size(); j++){
                    if(love[k] * v[i][j] < 0)  {
                        sum[(int)abs(v[i][j])] += 1.0 / v[i].size();
                    }
                }
            }
        }
    }
    maxn[1] = maxn[2] = -1;
    for(int k = 1; k <= 2; k++) {
        for(int i = 1; i <= 1000; i++) {
            if(love[k] * sex[i] < 0) {
                if(sum[i] > maxn[k]) {
                    maxn[k] = sum[i];
                    ans[k].clear();
                    ans[k].push_back(sex[i]);
                }else if(sum[i] == maxn[k]) {
                    ans[k].push_back(sex[i]);
                }
            }
        }
    }
    if(maxn[1] == sum[(int)abs(love[2])] && maxn[2] == sum[(int)abs(love[1])]) {
        string s1 = to_string(love[1]), s2 = to_string(love[2]);
        if(love[1] == 1000)  s1 = "0";
        if(love[1] == -1000)  s1 = "-0";
        if(love[2] == 1000)  s2 = "0";
        if(love[2] == -1000)  s2 = "-0";
        cout << s1 << " " << s2 << endl;
        return 0;
    }
    for(int k = 1; k <= 2; k++) {
        sort(ans[k].begin(), ans[k].end(), cmp);
        for(int i = 0; i < ans[k].size(); i++) {
            string s1 = to_string(love[k]), s2 = to_string(ans[k][i]);
            if(love[k] == 1000)  s1 = "0";
            if(love[k] == -1000)  s1 = "-0";
            if(ans[k][i] == 1000)  s2 = "0";
            if(ans[k][i] == -1000)  s2 = "-0";
            cout << s1 << " " << s2 << endl;
        }
    }
    return 0;
}

L2-029 特立独行的幸福

#include <bits/stdc++.h>
using namespace std;
int A, B, flag, num[10001], notIndep[10001];
bool isPrime(int a) {
	if (a == 1) return false;
	for (int i = 2; i <= sqrt(a); i++)
		if (a % i == 0) return false;
	return true;
}
bool isIndep(int x) {
	set<int> mark;
	int X = x, temp1, temp2;
	while (X != 1) {
		mark.insert(X);
		temp1 = 0;
		while (X) {
			temp2 = X % 10;
			X /= 10;
			temp1 += temp2 * temp2;
		}
		num[x]++;
		notIndep[temp1] = 1;
		X = temp1;
		if (mark.count(X)) return false;
	} 
	return true;
}
int main() {
	cin >> A >> B;
	vector<int> ans;
	for (int i = A; i <= B; i++)
		if (isIndep(i)) ans.push_back(i);
	for (int i = 0; i < ans.size(); i++) {
		if (isPrime(ans[i])) num[ans[i]] <<= 1;
		if (!notIndep[ans[i]]) {
			cout << ans[i] << ' ' << num[ans[i]] << endl;
			flag = 1;
		}
	}
	if (!flag) cout << "SAD"; 
	return 0;
}

L2-030 冰岛人

#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>

using namespace std;
typedef pair<int, string> PIS;
const int N = 100010;
map<string, PIS> record;    // 映射关系: 孩子的名 -> 父亲的名

string check(string s1, string s2)
{
    int cnt1 = 0, cnt2 = 0;
    while (s1 != "") 
    {
        cnt2 = 0;
        string s3 = s2;
        while (s3 != "") 
        {
            if (s3 == s1 && (cnt1 < 4 || cnt2 < 4)) return "No";
            if (cnt1 >= 4 && cnt2 >= 4) return "Yes";
            s3 = record[s3].second;
            cnt2 ++ ; 
        }
        s1 = record[s1].second;
        cnt1 ++ ;
    }
    return "Yes";
}

int main()
{
    int n, m; cin >> n;
    string fName, lName;
    for (int i = 0; i < n; i ++ )
    {
        cin >> fName >> lName;
        if (lName.back() == 'n') record[fName] = {1, lName.substr(0, lName.length()-4) };
        else if (lName.back() == 'r') record[fName] = {0, lName.substr(0, lName.length()-7) };
        else if (lName.back() == 'm') record[fName].first = 1;
        else record[fName].first = 0;
    }

    cin >> m;
    string fName1, fName2, tmp;
    for (int i = 0; i < m; i ++ )
    {
        cin >> fName1 >> tmp >> fName2 >> tmp;
        if (!record.count(fName1) || !record.count(fName2)) cout << "NA\n";
        else if (record[fName1].first == record[fName2].first) cout << "Whatever\n";
        else cout << check(fName1, fName2) << endl;
    }

    return 0;
}

L2-031 深入虎穴

#include <bits/stdc++.h>
using namespace std;
#define pii pair<int, int>
int N, K, D, one, vis[100001];
vector<int> Edge[100001];
queue<int> Q;
int main() {
	cin >> N;
	for (int i = 1; i <= N; ++i) {
		cin >> K;
		while(K--) {
			cin >> D;
			Edge[D].push_back(i);
			Edge[i].push_back(D);
		}
	}
	Q.push(1);
	vis[1] = 1;
	while(!Q.empty()) {
		one = Q.front();
		Q.pop();
		for (auto v:Edge[one]) {
			if (vis[v]) continue;
			vis[v] = 1;
			Q.push(v);
		}
	}
	cout << one;
	return 0;
}

L2-032 彩虹瓶

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 1010;
int stk[N];

int main()
{
    int n, m, k; cin >> n >> m >> k;

    for (int i = 0; i < k; i ++ )
    {
        bool flag = true;
        int idx = -1, cnt = 1, x;
        for (int j = 0; j < n; j ++ )
        {
            cin >> stk[++ idx];
            while (idx >= 0 && stk[idx] == cnt) idx --, cnt ++ ;
            if (idx + 1 > m)
            {
                flag = false;
                // break;
            }
        }
        if (idx == -1 && flag) puts("YES");
        else puts("NO");
    }

    return 0;
}

/*
	注意! 在这里不能直接break! 在这里我们是在输入时进行判断,即使你输入一部分就能判断NO,后面的数据依然要输入,等输入完才能进行判断,如果你提前终止,那么留在缓冲区的数据会影响会留给后面的cin接收,所以一定要等输入结束才能进行判断!
*/

L2-033 简单计算器

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 1010;
int n, in[N], res;
char op, record[N];

int main()
{
    cin >> n;
    for (int i = n - 1; i >= 0; i -- ) cin >> in[i];
    for (int i = n - 1; i > 0; i -- ) cin >> record[i];
    res = in[0];
    for (int i = 1; i <= n - 1; i ++ )
    {
        op = record[i];
        if (op == '+') res = in[i] + res;
        else if (op == '-') res = in[i] - res;
        else if (op == '*') res = in[i] * res;
        else
        {
            if (res == 0)
            {
                printf("ERROR: %d/0\n", in[i]);
                return 0;
            }
            res = in[i] / res;
        }
    }
    cout << res << endl;

    return 0;
}

L2-034 口罩发放

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <set>

using namespace std;
const int N = 10010;

struct node {
    string name, id, time;
    int isIll, order;
};

bool isLegal(const string &s)
{
    if (s.size() != 18) return false;
    for (auto it : s) if (!isdigit(it)) return false;
    return true;
}

// 容器结构体排序用const
bool cmp(const node &a, const node &b)
{
    if (a.time != b.time) return a.time < b.time;
    return a.order < b.order;
}

int D, P, S, T, providedNum;
vector<node> record, ill;
unordered_map<string, int> lastGet;
set<string> gotten;

int main()
{
    cin >> D >> P;
    for (int i = 1; i <= D; i ++ )
    {
        cin >> T >> S;
        record.resize(T);
        providedNum = 0;
        // 先对每一组的记录进行处理输出, 同时将状态为1的用户添加到ill中, 最后进行输出
        for (int j = 0; j < T; j ++ )
        {
            cin >> record[j].name >> record[j].id >> record[j].isIll >> record[j].time;
            record[j].order = j;
            if (!isLegal(record[j].id)) record[j].name = "";
            else
            {
                // 添加 ill 信息
                if (!lastGet.count(record[j].id)) lastGet[record[j].id] = -100;
                if (record[j].isIll == 1 && !gotten.count(record[j].id) )
                {
                    ill.push_back(record[j]);
                    gotten.insert(record[j].id);
                }
            }
        }
        sort(record.begin(), record.end(), cmp);
        for (int j = 0; j < T && providedNum < S; j ++ )
        {
            if (record[j].name != "" && i - lastGet[record[j].id] > P)
            {
                lastGet[record[j].id] = i;
                providedNum ++ ;
                cout << record[j].name << " " << record[j].id << endl;
            }
        }
    }
    for (auto it : ill) cout << it.name << " " << it.id << endl;

    return 0;
}

L2-035 完全二叉树的层序遍历

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 50;
int n, idx, post[N], lev[N];

// 后序 -> 层序 下标表示了层序遍历的顺序
void level(int i)
{
    if (i > n) return;
    level(i << 1);
    level(i << 1 | 1);
    lev[i] = post[idx ++ ];
}

int main()
{
    cin >> n;
    for (int i = 0; i < n; i ++ ) cin >> post[i];
    level(1);
    cout << lev[1];
    for (int i = 2; i <= n; i ++ ) cout << " " << lev[i];

    return 0;
}

L2-036 网红点打卡攻略

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 210, INF = 0x3f3f3f3f;
int n, m, k, g[N][N], cnt[N], path[N];

int main()
{
    cin >> n >> m;
    int a, b, c;
    memset(g, INF, sizeof g);
    for (int i = 0; i < m; i ++ )
    {
        cin >> a >> b >> c;
        g[a][b] = g[b][a] = c;
    }

    cin >> k;
    int mincost = INF, id = -1, num = 0;
    for (int i = 1; i <= k; i ++ )
    {
        int u, cost = 0;
        path[0] = path[n + 1] = 0;
        cin >> u;
        bool flag = false;
        memset(cnt, 0, sizeof cnt);
        for (int j = 1; j <= u; j ++ )
        {
            cin >> path[j];
            if (cnt[path[j]]) path[0] ++ ;
            cnt[path[j]] ++ ;
        }

        if (u != n || path[0]) continue;

        for (int j = 1; j <= n + 1; j ++ )
        {
            if (g[path[j]][path[j - 1]] == INF)
            {
                flag = true;
                break;
            }
            cost += g[path[j]][path[j - 1]];
        }

        if (flag) continue;

        num ++ ;
        if (cost < mincost)
        {
            id = i;
            mincost = cost;
        } else if (cost == mincost) {
            id = min(id, i);
        }
    }

    cout << num << endl << id << " " << mincost << endl;

    return 0;
}

/// 另一种做法
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 10010;
vector<int> child[maxn];
//目前序列和结果序列
vector<int> path, ans;
int father[maxn];
int n, k;
int temp;
int maxDepth = 0;

void DFS(int s, int depth)
{
	if (child[s].size() == 0)
	{
		if (depth > maxDepth)
		{
			maxDepth = depth;
			ans = path;
		}
		return;
	}
	for (int i = 0; i < child[s].size(); i++)
	{
		path.push_back(child[s][i]);
		DFS(child[s][i], depth + 1);
		//记得回退
		path.pop_back();
	}
}

int main()
{
	cin >> n;
	for (int i = 0; i < n; i++)
		father[i] = i;
	for (int i = 0; i < n; i++)
	{
		cin >> k;
		for (int j = 0; j < k; j++)
		{
			cin >> temp;
			child[i].push_back(temp);
			father[temp] = i;
		}
		//排序
		if (child[i].size() != 0)
			sort(child[i].begin(), child[i].end(), less<int>());
	}
	int root;
	for (int i = 0; i < n; i++)
	{
		if (father[i] == i)
			root = father[i];
	}
//	cout << root << endl;
	path.push_back(root);
	DFS(root, 1);
	cout << maxDepth << endl;
//	cout << ans.size() << endl;
	for (int i = 0; i < ans.size(); i++)
	{
		cout << ans[i];
		if (i != ans.size() - 1)
			cout << " ";
	}
	return 0;
}

L2-037 包装机

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>

using namespace std;
const int N = 1010;
queue<char> q[N];
stack<char> stk;

int main()
{
    int n, m, smax; cin >> n >> m >> smax;
    string s;
    for (int i = 1; i <= n; i ++ )
    {
        cin >> s;
        for (int j = 0; j < s.size(); j ++ ) q[i].push(s[j]);
    }

    int op;
    while (cin >> op)
    {
        if (op == -1) break;
        if (op == 0)
        {
            if (stk.empty()) continue;
            cout << stk.top();
            stk.pop();
        } else {
            if (q[op].empty()) continue;
            if (stk.size() == smax)
            {
                cout << stk.top();
                stk.pop();
            }
            stk.push(q[op].front());
            q[op].pop();
        }
    }

    return 0;
}

L2-038 病毒溯源

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
const int N = 10010;
bool st[N];
int lev = -1, p[N], id = -1;

void dfs(int u, int v, vector<vector<int> > &vv)
{
    if (v > lev)
    {
        lev = v;
        id = u;
    }
    for (auto t : vv[u])
    {
        dfs(t, v + 1, vv);
    }
}

int main()
{
    int n, k, x; cin >> n;
    vector<vector<int> > v(n);
    memset(p, -1, sizeof p);
    for (int i = 0; i < n; i ++ )
    {
        cin >> k;
        for (int j = 0; j < k; j ++ )
        {
            cin >> x;
            p[x] = i;
            st[x] = true;
            v[i].push_back(x);
        }
        sort(v[i].begin(), v[i].end());
    }

    int fi = -1;
    for (int i = 0; i < n; i ++ )
        if (!st[i]) fi = i;

    dfs(fi, 1, v);
    cout << lev << endl;
    vector<int> ans;
    while (id != fi)
    {
        ans.push_back(id);
        id = p[id];
    }
    ans.push_back(id);

    cout << ans[ans.size() - 1];
    for (int i = ans.size() - 2; i >= 0; i -- )
    {
        cout << " " << ans[i];
    }

    return 0;
}

L2-039 清点代码库

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>

using namespace std;
const int N = 10010;
int n, m, t;
vector<int> tmp;
map<vector<int>, int> A;
multimap<int, vector<int>, greater<int>> B; // multimap - 允许存在重复键

int main()
{
    cin >> n >> m;
    tmp.resize(m);
    for (int i = 0; i < n; i ++ )
    {
        for (int j = 0; j < m; j ++ ) cin >> tmp[j];
        A[tmp] ++ ;
    }

    for (auto it : A) B.insert({it.second, it.first});
    cout << A.size() << endl;
    for (auto it : B)
    {
        cout << it.first;
        for (auto it2 : it.second) cout << " " << it2;
        cout << endl;
    }

    return 0;
}

L2-040 哲哲打游戏

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
const int N = 100010;
vector<int> v[N];
int archive[110];

int main()
{
    int n, m, k; cin >> n >> m;

    int x;
    for (int i = 1; i <= n; i ++ )
    {
        cin >> k;
        for (int j = 1; j <= k; j ++ )
        {
            cin >> x;
            v[i].push_back(x);
        }
    }

    int op, idx = 1;
    for (int i = 1; i <= m; i ++ )
    {
        cin >> op >> x;
        if (op == 0)
        {
            idx = v[idx][x - 1];
        } else if (op == 1) {
            archive[x] = idx;
            cout << idx << endl;
        } else {
            idx = archive[x];
        }
    }
    cout << idx << endl;

    return 0;
}


L3

L3-001 凑零钱

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
const int N = 10010;
int f[N], w[N]; // 一维滚动数组
bool st[N][N];
int cmp(int a, int b) {return a > b; }

int main()
{
    int n, m; cin >> n >> m;
    for (int i = 1; i <= n; i ++ ) cin >> w[i];
    sort(w + 1, w + n + 1, cmp);
    for (int i = 1; i <= n; i ++ )
        for (int j = m; j >= w[i]; j -- )
    if (f[j] <= f[j - w[i]] + w[i]) {
        st[i][j] = true;    // 选取
        f[j] = f[j - w[i]] + w[i];
    }

    if (f[m] != m) puts("No Solution");
    else {
        vector<int> res;
        int v = m, idx = n;
        while (v > 0) {
            if (st[idx][v]) {
                res.push_back(w[idx]);
                v -= w[idx];
            }
            idx -- ;
        }
        for (int i = 0; i < res.size(); i ++ ) {
            cout << res[i];
            if (i == res.size() - 1) cout << endl;
            else cout << " ";
        }
    }

    return 0;
}

L3-003 社交集群

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;
const int N = 1010;
int p[N], f[N], root[N]; // f 为喜欢第i个编号的人
int cmp(int a, int b) {return a > b; }

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

void Union(int a, int b)
{
    p[find(a)] = find(b);
}

int main()
{
    int n, k, t, cnt = 0;
    scanf("%d", &n);
    for (int i = 1; i <= n; i ++ ) p[i] = i;
    for (int i = 1; i <= n; i ++ ) {
        scanf("%d:", &k);
        for (int j = 1; j <= k; j ++ )
        {
            scanf("%d", &t);
            if (f[t] == 0) f[t] = i;
            Union(i, find(f[t]));
        }
    }
    for (int i = 1; i <= n; i ++ ) root[find(i)] ++ ;
    for (int i = 1; i <= n; i ++ ) {
        if (root[i]) cnt ++ ;
    }
    printf("%d\n", cnt);
    sort(root, root + N, cmp);
    for (int i = 0; i < cnt; i ++ ) {
        printf("%d", root[i]);
        if (i == cnt - 1) printf("\n");
        else printf(" ");
    }

    return 0;
}

L3-004 肿瘤诊断

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

using namespace std;
const int N = 1010;
struct node {
    int x, y, z;
};
int m, n, l, t;
int dx[6] = {1, 0, 0, -1, 0, 0};
int dy[6] = {0, 1, 0, 0, -1, 0};
int dz[6] = {0, 0, 1, 0, 0, -1};
int g[1300][130][80];
bool st[1300][130][80];
bool judge(int x, int y, int z) {
    if (x < 0 || x >= m || y < 0 || y >= n || z < 0 || z >= l) return false;
    if (g[x][y][z] == 0 || st[x][y][z]) return false;
    return true;
}

int bfs(int x, int y, int z) {
    int cnt = 0;
    node tmp;
    tmp.x = x, tmp.y = y, tmp.z = z;
    queue<node > q;
    q.push(tmp);
    st[x][y][z] = true;
    while (!q.empty()) {
        node top = q.front(); q.pop();
        cnt ++ ;
        for (int i = 0; i < 6; i ++ ) {
            int tx = top.x + dx[i];
            int ty = top.y + dy[i];
            int tz = top.z + dz[i];
            if (judge(tx, ty, tz)) {
                st[tx][ty][tz] = true;
                tmp.x = tx, tmp.y = ty, tmp.z = tz;
                q.push(tmp);
            }
        }
    }
    if (cnt >= t) return cnt;
    else return 0;
}

int main()
{
    cin >> m >> n >> l >> t;
    // 注意输入的顺序
    for (int i = 0; i < l; i ++ )
        for (int j = 0; j < m; j ++ )
            for (int k = 0; k < n; k ++ )
                cin >> g[j][k][i];

    int res = 0;
    for (int i = 0; i < l; i ++ )
        for (int j = 0; j < m; j ++ )
            for (int k = 0; k < n; k ++ )
                if (g[j][k][i] && !st[j][k][i]) {
                    res += bfs(j, k, i);
                }

    cout << res << endl;

    return 0;
}

L3-005 垃圾箱分布

#include <cstdio>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;
const int inf = 999999999;
int n, m, k, ds, station;
int e[1020][1020], dis[1020];
bool visit[1020];
int main() {
    fill(e[0], e[0] + 1020 * 1020, inf);
    fill(dis, dis + 1020, inf);
    scanf("%d%d%d%d", &n, &m, &k, &ds);
    for(int i = 0; i < k; i++) {
        int tempdis;
        string s, t;
        cin >> s >> t >> tempdis;
        int a, b;
        if(s[0] == 'G') {
            s = s.substr(1);
            a = n + stoi(s);
        } else {
            a = stoi(s);
        }
        if(t[0] == 'G') {
            t = t.substr(1);
            b = n + stoi(t);
        } else {
            b = stoi(t);
        }
        e[a][b] = tempdis;
        e[b][a] = tempdis;
    }
    int ansid = -1;
    double ansdis = -1, ansaver = inf;
    for(int index = n + 1; index <= n + m; index++) {
        double mindis = inf, aver = 0;
        fill(dis, dis + 1020, inf);
        fill(visit, visit + 1020, false);
        dis[index] = 0;
        for(int i = 0; i < n + m; i++) {
            int u = -1, minn = inf;
            for(int j = 1; j <= n + m; j++) {
                if(visit[j] == false && dis[j] < minn) {
                    u = j;
                    minn = dis[j];
                }
            }
            if(u == -1) break;
            visit[u] = true;
            for(int v = 1; v <= n + m; v++) {
                if(visit[v] == false && dis[v] > dis[u] + e[u][v])
                    dis[v] = dis[u] + e[u][v];
            }
        }
        for(int i = 1; i <= n; i++) {
            if(dis[i] > ds) {
                mindis = -1;
                break;
            }
            if(dis[i] < mindis) mindis = dis[i];
            aver += 1.0 * dis[i];
        }
        if(mindis == -1) continue;
        aver = aver / n;
        if(mindis > ansdis) {
            ansid = index;
            ansdis = mindis;
            ansaver = aver;
        } else if(mindis == ansdis && aver < ansaver) {
            ansid = index;
            ansaver = aver;
        }
    }
    if(ansid == -1)
        printf("No Solution");
    else {
        printf("G%d\n", ansid - n);
        printf("%.1f %.1f", ansdis, ansaver);
    }
    return 0;
}

L3-007 天梯地图


L3-008 喊山

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>

using namespace std;
const int N = 10010;
vector<vector<int> > g(N);
bool st[N];
int lev[N];

int bfs(int t)
{
    memset(st, false, sizeof st);
    memset(lev, 0, sizeof lev);
    int maxlev = -1, id = N;
    queue<int> q;
    q.push(t);
    st[t] = true;
    while (!q.empty()) {
        int h = q.front(); q.pop();
        if (lev[h] > maxlev) {
            maxlev = lev[h];
            id = N;
        }
        if (h != t)
            id = min(id, h);
        for (int i = 0; i < g[h].size(); i ++ ) {
            if (!st[g[h][i]]) {
                st[g[h][i]] = true;
                q.push(g[h][i]);
                lev[g[h][i]] = lev[h] + 1;
            }
        }
    }

    if (id != N) return id;
    else return 0;
}

int main()
{
    int n, m, k; cin >> n >> m >> k;
    int a, b;
    for (int i = 0; i < m; i ++ ) {
        cin >> a >> b;
        g[a].push_back(b);
        g[b].push_back(a);
    }

    int t;
    for (int i = 0; i < k; i ++ ) {
        cin >> t;
        cout << bfs(t) << endl;
    }

    return 0;
}

L3-010 是否完全二叉搜索树

#include <cstdio>
using namespace std;
int tree[1<<20];
int num;
void BST(int a) {
    if(tree[a] == 0)
        tree[a] = num;
    else if(tree[a] < num)
        BST(a<<1);
    else
        BST(a<<1|1);
}
int main() {
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++) {
        scanf("%d", &num);
        BST(1);
    }
    bool flag = true;
        for(int cnt = 1, k = 1; cnt <= n; k++) {
            if(tree[k] == 0)
                flag = false;
            else {
                printf("%d", tree[k]);
                if(cnt++ != n) printf(" ");
            }
        }
    if(flag) printf("\nYES");
    else printf("\nNO");
    return 0;
}

L3-011 直捣黄龙


L3-014 周游世界


L3-015 球队“食物链”


L3-016 二叉搜索树的结构


L3-018 森森美图


L3-019 代码排版 (模拟)


L3-022 地铁一日游


L3-028 森森旅游


L3-029 还原文件


举报

相关推荐

0 条评论