首页 > 其他分享 >Atcoder ABC299 E-G

Atcoder ABC299 E-G

时间:2024-08-05 11:50:33浏览次数:7  
标签:Atcoder 每个 int res st ABC299 push 顶点

Atcoder ABC299 E-G

E - Nearest Black Vertex

链接:

E - Nearest Black Vertex (atcoder.jp)

简要题意:

  • 问题陈述

    给你一个简单连接的无向图,有 \(N\) 个顶点和 \(M\) 条边(简单图不包含自循环和多条边)。
    在 \(i = 1, 2, \ldots, M\) 中, \(i\) -th 边双向连接顶点 \(u_ i\) 和顶点 \(v_ i\) 。

    请判断是否有办法将每个顶点涂成黑色或白色以同时满足以下两个条件,如果存在,请给出一个这样的办法。

    • 至少有一个顶点被涂成黑色。
    • 对于每个 \(i = 1, 2, \ldots, K\) 都成立:
      • 顶点 \(p_ i\) 与涂成黑色的顶点之间的最小距离正好是 \(d_i\) 。

    这里,顶点 \(u\) 和顶点 \(v\) 之间的距离是连接 \(u\) 和 \(v\) 的路径中边的最小数量。

思路:

  • 先找到每个到\(p_ i\)距离为\(d_i\)的点,我们称之为可行点
  • 那非可行点是什么呢,就是到\(p_ i\)短于\(d_i\)的点,这些点需要排除在外
  • 然后对于每个\(p_i\)用可行点中挑出不可行点,即是答案

代码:

const int N = 200005;
int n,m;
vector<int> e[N];
int nin[N]; //排除在外的数字,白色数字
vector<int> can[N]; //可能的数字;
map<int,int> hd;// 每个数字对于黑色的最短距离
void solve(){
    cin >> n >> m;
    for(int i = 1; i <= m;i++){
        int u,v;
        cin >> u >> v;
        e[u].push_back(v);
        e[v].push_back(u);
    }
    int q;
    cin >> q;
    for(int i = 1;i<=q;i++){
        int u,d;
        cin >> u >> d;
        hd[u] = d;
    }
    if(q==0){
        cout << "Yes" << endl;
        for(int i = 1;i<=n;i++){
            cout << 1;
        }
        return;
    }
    int vis[n + 1];
    for(int i = 1;i<=n;i++){
        if(!hd.count(i)){
            continue;
        }
        memset(vis,0,sizeof vis);
        int d = hd[i];
        if(d==0){
            can[i].push_back(i);
            continue;
        }
        queue<pair<int,int>> q;
        q.push({i,0});
        while(q.size()){
            auto p = q.front();q.pop();
            int u = p.first,val = p.second;
            if(vis[u]) continue;
            if(val<d){
                nin[u]=1;
            }
            if(val==d){
                can[i].push_back(u);
                continue;
            }
            if(val>d) continue;
            vis[u] = 1;
            for(auto v:e[u]){
                q.push({v,val+1});
            }
        }
    }
    int res[n + 1];
    memset(res,0,sizeof res);
    for(int i = 1;i<=n;i++){
        if(!hd.count(i)) continue;
        int cnt = 0;
        for(auto p:can[i]){
            if(!nin[p]){
                cnt++;
                res[p] = 1;
            }
        }
        if(!cnt){
            cout << "No" << endl;
            return;
        }
    }
    cout << "Yes" << endl;
    for(int i = 1;i<=n;i++){
        cout << res[i];
    }
}   

G - Minimum Permutation

链接:

G - Minimum Permutation (atcoder.jp)

简要题意:

  • 问题陈述

    长度为 \(N\) 的序列 \(A\) 由 \(1\) 和 \(M\) 之间的整数组成。其中,从 \(1\) 到 \(M\) 的每个整数都至少在 \(A\) 中出现过一次。

    在 \(A\) 的长度为 \(M\) 的子序列中,每个 \(1, \ldots, M\) 都出现过一次,请找出字典序最小的一个。

思路:

  • 很明显我们对于一个1至M的数有保留和删除两种操作
  • 什么时候不能删除?,在后面数组中没有这个数字了就不能删除
  • 这样我们可以建一个表记录每个数字最后出现的位置
  • 然后用单调栈保持数组的最小即可
  • 注意还要开一个表记录数字是否在栈中

代码:

const int N = 200005;
int last[N],a[N],instk[N];
void solve(){
	int n,k;
	cin >> n >> k;
	for(int i = 1;i<=n;i++){
		int t;
		cin >>t;
		a[i] = t;
		last[t] = i;
	}
	stack<int> st;
	for(int i = 1;i<=n;i++){
		if(instk[a[i]]) continue;
		while(!st.empty() && a[i] < st.top() && last[st.top()] > i){
			instk[st.top()]=0;
			st.pop();
		}
		st.push(a[i]);
		instk[a[i]]=1;
	}
	vector<int> res;
	while(st.size()){
		res.push_back(st.top());st.pop();
	}
	for(int i = res.size() - 1;i>=0;i--){
		cout << res[i] << " ";
	}
}

标签:Atcoder,每个,int,res,st,ABC299,push,顶点
From: https://www.cnblogs.com/bananawolf/p/18342944

相关文章

  • AtCoder Beginner Contest 365
    AtCoderBeginnerContest365A-LeapYear给出年份,判断这一年有多少天闰年条件已经给出,逐条判断模拟即可。#include<iostream>usingnamespacestd;intmain(){inty;cin>>y;if(y%400==0||y%4==0&&y%100!=0)cout<<366<<endl;else......
  • AtCoder Beginner Contest 365
    F-TakahashionGrid用线段树上的节点维护一下\((l,r,c)\),如果\(c\)为\(-1\):\(l,r\)表示这一段区间内\([l,r]\)的交。如果\(c\ne-1\),\(l,r\)表示这一段第一次上下界相等的时候的位置为\(l\),合并后走出来的位置为\(r\),然后转折的步数为\(c\)。然后这玩意可以合并......
  • 【A~E】AtCoder Beginner Contest 365
    A-LeapYear题目大意给定\(n\),求第\(n\)年的天数(\(365\)或\(366\))。思路显然地,我们需要判断这个是否为闰年。如果\(n\)不能被\(4\)整除,那么不是闰年。如果\(n\)可以被\(400\)整除,那么是闰年。如果\(n\)不可以被\(100\)整除但是可以被\(4\)整除,那么是......
  • AtCoder Beginner Contest 365 补题记录(A~E,G)
    Perf2000+,但是补不回来上场超低的Rating/llA#include<bits/stdc++.h>#defineintlonglongusingnamespacestd;signedmain(){intn;cin>>n;if(n%400==0)cout<<"366\n";elseif(n%100==0)cout<<"365\n";......
  • AtCoder Beginner Contest 365 随笔
    擦,F假了A判断闰年B输出次大值的下标用pair排序后即可C给定一个数组\(A_n\)和整数\(M\),尝试找到一个最大的\(m\),使得:\[\sum_{i=1}^n\min(A_i,m)\leM\]不等号左边显然随着\(m\)的增大而增大,所以可以二分一个\(m\),然后判断即可D两个人玩\(n\)局剪刀石头布......
  • Atcoder ABC298 D-F
    AtcoderABC298D-FD-WritingaNumeral链接:D-WritingaNumeral(atcoder.jp)简要题意:问题陈述我们有一个字符串\(S\)。初始值为\(S=\)1.按以下格式依次处理\(Q\)查询。1x:在\(S\)的末尾添加一个数字\(x\)。2:删除\(S\)开头的数字。3:以十进制形......
  • 每日一题——A - Max/Min AtCoder - abc356_e
    1.题目大意:枚举两个数的Max/Min向下取整之和。2.思路:一开始并没有想时间复杂度问题发现通过sort()排序来遍历每个最小值Min和后面最大值的和就是题目答案。你会发现仍然有问题,那就是取整的问题你就必须要优化然后发现很明显超时了。现在我们来换一个角度思考。搭配前缀和嘛。为......
  • Atcoder ABC297 E-G
    AtcoderABC297E-GE-KthTakoyakiSet链接:E-KthTakoyakiSet简要题意:问题陈述有\(N\)种章鱼烧出售。一个\(i\)-种的章鱼烧售价为\(A_i\)日元。高桥总共至少会买一个章鱼烧。他可以购买多个同类章鱼烧。求高桥可能支付的\(K\)个最低价格。在这里,如果有多......
  • Solution - Atcoder AGC052B Tree Edges XOR
    令\(w_{(u,v)}\)为边\((u,v)\)的边权。考虑到对于一条边进行操作影响的是有公共点的边,于是一个想法是把边权转到点权,用点权来表示边权。于是考虑对于每个点构造\(w_u\)使得\(w_{(u,v)}=w_u\oplusw_v\)。因为这是一颗树,所以一定存在合法的构造。其实到了这里,这种......
  • Atcoder ABC296 F
    AtcoderABC296FF-SimultaneousSwap链接:F-SimultaneousSwap(atcoder.jp)简要题意:问题陈述给你两个\(N\)数字序列:\(A=(A_1,A_2,\ldots,A_N)\)和\(B=(B_1,B_2,\ldots,B_N)\)。高桥可以重复下面的操作任意多次(可能为零)。在\(1\)和\(N\)之间选择三......