AtCoder Beginner Contest 209

D – Collision

题目描述:

给一颗树,q次询问,每次询问给两个点xy,两个点上放两个人以相同的速度,沿着二者的最短路前进,问二者会在点上相遇,还是在边上相遇

思路:

不难发现,对于任意两个点xy,如果二者在树上的最短距离是奇数,则在边上相遇,否则在点上相遇

树上最短距离可以用lca求,但是这里没必要这么求,我们只需要知道二者距离的奇偶性即可,那我们可以对整个图进行黑白染色,如果颜色相同,则是在点上相遇,否则是在边上相遇

#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define inf 0x3f3f3f3f
#define mod7 1000000007
#define mod9 998244353
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(a) cout << "Debuging...|" << #a << ": " << a << "\n";
typedef long long ll;
typedef pair <int,int> pii;

#define MAX 300000 + 50
int n, m, k, x;
vector<int>G[MAX];
int col[MAX];
void dfs(int u, int op){
    col[u] = op;
    for(auto v : G[u]){
        if(col[v] == -1)dfs(v, op ^ 1);
    }
}
void work(){
    cin >> n >> m;
    for(int i = 1, a, b; i < n; ++i){
        cin >> a >> b;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    mem(col, -1);
    dfs(1, 0);
    for(int i = 1, a, b; i <= m; ++i){
        cin >> a >> b;
        if(col[a] != col[b])cout << "Road\n";
        else cout << "Town\n";
    }
}


int main(){
    io;
    work();
    return 0;
}

 

E – Shiritori

题目描述:

成语接龙,有n个长度大于等于3的字符串,当前说到s,下次说的字符串的前3个字符必须和s的后三个完全相同

Takahashi先手,Aoki后手,二者轮流说成语,谁先不能说出成语则输,每个串都可以使用任意多次

问以第i个字符串为开头的时候,谁会赢,如果陷入循环,则输出Draw

思路:

又是一个对抗博弈的题目

建图肯定不可取,我们发现,只存在大小写的字母,且只有三位有用,所以可以对每个串,哈希出前三位和后三位,得到uv,建u->v就行

考虑状态,以点u为起点时,如果先手必输,则ans[u]=0,如果先手必赢,则ans[u]=1

  • 如果一个点没有任何的出边,那这个点就是先手必输,即不存在串使的该点能转移到别的点
  • 如果一个点一步只能走到先手必胜点,则他先手必输
  • 如果一个点可以一步走到一个先手必输点,则他先手必赢
  • 如果这个点既不是先手必胜点和不是先手必输点,则是平局点

对于一般来说的对抗博弈题,我们都是去跑dfs,但是这里存在可以循环的点,dfs不好判,所以改成bfs,改成bfs的时候就需要注意了,之前跑dfs的时候,我们是去递归跑完所有子节点,所以最先确定状态的其实所有出度为0的点,如果是博弈树的话,也就是所有叶子节点,所以改成bfs的时候,我们应该先确定叶子节点,也就是出度为0的点,也就是需要我们反向建图,对于出度为0的点,他们的状态就是先手必输,状态为0。遇到状态确定的点就跳过,否则,我们就给出度减1,如果当前点u是先手必输,那对于u的子节点v,他的状态就是先手必胜,即1,并给他塞队列里;如果v的出度已经归0,此时他还没有确实状态,则说明能到达他的点都是必胜点,则他就是必输点,赋状态为0,并给他塞到队列里

输出结果的时候,我们应该判断后三个字母对应的状态,因为以当前串为起始串时,我们先手的人一定会用这个串,而我们求的状态可没有这个规定,所以我们判后三个字母为起始串就可以

#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define inf 0x3f3f3f3f
#define mod7 1000000007
#define mod9 998244353
#define m_p(a,b) make_pair(a, b)
#define mem(a,b) memset((a),(b),sizeof(a))
#define io ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(a) cout << "Debuging...|" << #a << ": " << a << "\n";
typedef long long ll;
typedef pair <int,int> pii;

#define MAX 300000 + 50
int n, m, k, x;
int tr[MAX];
string s;

int getid(char x){
    if(x >= 'A' && x <= 'Z')return x - 'A';
    else return x - 'a' + 26;
}

int calc(char a, char b, char c){
    return getid(a) * 52 * 52 + getid(b) * 52 + getid(c);
}
vector<int>G[MAX];
int du[MAX];
int ans[MAX];
void work(){
    cin >> n;
    for(int i = 1; i <= n; ++i){
        cin >> s;
        int a = calc(s[0], s[1], s[2]);
        int b = calc(s[(int)s.size() - 3], s[(int)s.size() - 2], s[(int)s.size() - 1]);
        G[b].push_back(a);
        ++du[a];
        tr[i] = b;
    }
    mem(ans, -1);
    queue<int>q;
    for(int i = 0; i < 52 * 52 * 52 + 5; ++i){
        if(!du[i]){
            ans[i] = 0;
            q.push(i);
        }
    }
    while (!q.empty()) {
        int u = q.front();q.pop();
        for(auto v : G[u]){
            if(ans[v] != -1)continue;
            --du[v];
            if(ans[u] == 0){
                ans[v] = 1;
                q.push(v);
            }
            else if(du[v] == 0){
                ans[v] = 0;
                q.push(v);
            }
        }
    }
    for(int i = 1; i <= n; ++i){
        int p = ans[tr[i]];
        if(p == 0)cout << "Takahashi\n";
        else if(p == 1)cout << "Aoki\n";
        else cout << "Draw\n";
    }
}


int main(){
    io;
    work();
    return 0;
}

 

博客内容均系原创,未经允许严禁转载!
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇