首页 > 其他分享 >AtCoder Beginner Contest 209(D,E)

AtCoder Beginner Contest 209(D,E)

时间:2023-05-08 22:24:24浏览次数:53  
标签:AtCoder Beginner 209 define long int maxn include dis

AtCoder Beginner Contest 209(D,E)

D(树,lca)

D

这个题给出\(n\)个点,\(n-1\)条边,有两个人,一个人在\(c\)点,一个人在\(d\)点,两人以相同的速度朝着对方走来(并且都是按照最短路的走法),问这两个人相遇是在点上,还是在路上

这一题意很好知道,就是判断这两点之间的最短距离的奇偶性

然后我就一个一个地去求最短路了,结果毫不意外的超时了

但是这个我感觉就是这个最短路迷惑了我

其实这道题告诉我们总共有\(n-1\)条路了,我们就应该知道这个在没有重边的情况下是一棵树,而且每一条边的距离都是一样的,那么对于这样的一棵树来说,好像两点之间的距离就直接是可求的,即\(dis_c+dis_d-2\times dis_{lca(c,d)}\)

然后这个\(2\times dis_{lca(c,d)}\)不会影响奇偶性,那么奇偶性就看\(dis_c+dis_d\)了

所以我们只需要知道\(dis_c\)和\(dis_d\)的和即可

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <unordered_map>
#include <array>
#include <cstring>
using namespace std;
#define int long long 
#define LL long long
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define inf 1e18
#define INF 1e18
#define mem(a,b) memset((a),(b),sizeof(a))
const double eps=1e-9;
const int maxn=2e5+10;
const int mod=1e9+7;
int n,q;
vector<int>g[maxn];
int dis[maxn];
void dfs(int u,int fa)
{
   dis[u]=dis[fa]+1;
   for (auto v:g[u])
   {
      if(v==fa) continue;
      dfs(v,u);
   }
   return ;
}
signed main() 
{
   cin>>n>>q;
   for (int i=1;i<n;i++)
   {
      int u,v;
      cin>>u>>v;
      g[u].push_back(v);
      g[v].push_back(u);
   }
   dfs(1,0);
   while (q--)
   {
      int x,y;
      cin>>x>>y;
      int flag=dis[x]+dis[y];
      if(flag&1)
      {
         cout<<"Road\n";
      }
      else 
      {
         cout<<"Town\n";
      }
   }
   system ("pause");
    return 0;
}

E(博弈,拓扑,图)

E

这个题意大致就是两个人,每次都必须选择上一个人选择的一个字符串的最后三个字符作为最前面三个字符的字符串,知道某人找不到这样的字符串,那么这个人就输了(类似于词语接龙)

这个题乍一看看不出什么规律,只能根据最原始的判断方法,第一步都不能找到成功的解法,先手必败,对于后面的步骤,如果下一步先手是必败,那么这一步必胜,如果这一步只能到达必败的状态,那么这一步也是必败

然后这个题还会存在平局,那就就意味着这个题出现了环,(刚好拓扑排序里面没有访问到的就是环)

然后我们就直接以上规律求出解

但是每次输入的字符串要怎么转化成边呢

我们可以对于一个字符串,最主要的就是前三个字符\(pre\)和后三个字符\(suf\),我们首先把这两个字符转化成\(hash\)值,然后我们可以建造反图,如果是最开始的,那么就意味着它后面没有可选字符串了,可以得知最开始的一部分字符串的状态,然后这些字符串通过拓扑排序来寻找它其他字符的状态

具体可看代码

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include<cmath>
#include <unordered_map>
#include <array>
#include <cstring>
using namespace std;
#define int long long 
#define LL long long
#define ios  ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define inf 1e18
#define INF 1e18
#define mem(a,b) memset((a),(b),sizeof(a))
const double eps=1e-9;
const int maxn=2e5+10;
const int mod=1e9+7;
int n;
vector<int>g[maxn];
int in[maxn];
int star[maxn];
int ans[maxn];
set<int>id;
int get(string s)
{
   int res=0;
   for (int i=0;i<s.size();i++)
   {
      int now=0;
      if(s[i]>='a'&&s[i]<='z')
      {
         now=s[i]-'a';
      }
      else 
      {
         now=s[i]-'A'+26;
      }
      res=res*52+now;
   }
   return res;
}
signed main() 
{
   cin>>n;
   for (int i=1;i<=n;i++)
   {
      string s;
      cin>>s;
      string pre=s.substr(0,3);
      string suf=s.substr(s.size()-3,3);
      int u=get(suf),v=get(pre);
      id.insert(u);
      id.insert(v);
      g[u].push_back(v);
      in[v]++;
      star[i]=u;
      ans[u]=-1;
   }
   queue<int>q;
   for (auto x:id)
   {
      if(in[x]==0)
      {
         q.push(x);
         ans[x]=0;
      }
   }
   while (!q.empty())
   {
      int u=q.front();
      q.pop();
      for (auto v:g[u])
      {
         if(ans[v]==-1)
         {
            in[v]--;
            if(ans[u]==0)
            {
               ans[v]=1;
               q.push(v);
            }
            else if(in[v]==0)
            {
               ans[v]=0;
               q.push(v);
            }
         }
      }
   }
   for (int i=1;i<=n;i++)
   {
      if(ans[star[i]]==-1)
      {
         cout<<"Draw\n";
      }
      else if(ans[star[i]]==1)
      {
         cout<<"Aoki\n";
      }
      else 
      {
         cout<<"Takahashi\n";
      }
   }
   system ("pause");
    return 0;
}

标签:AtCoder,Beginner,209,define,long,int,maxn,include,dis
From: https://www.cnblogs.com/righting/p/17383319.html

相关文章

  • Atcoder Grand Contest 046 D - Secret Passage
    思路挺自然的一道agc。首先发现删除完字符后的状态可以用一个三元组\((i,j,k)\)表示,其中\(i\)表示删除完之后只剩\([i+1,n]\)的后缀,\(j\)表示可以在后面插入\(j\)个\(0\),\(k\)表示可以在后面插入\(k\)个\(1\),显然不同的三元组能够得到的串是不同的,而一组三元组可......
  • AtCoder Regular Contest 159简要题解
    AtCoderRegularContest159传送门A-CopyandPasteGraph图的邻接矩阵为\[\left(\begin{matrix}A&A&\cdots&A\\A&A&\cdots&A\\\cdots&\cdots&\cdots&\cdots\\A&A&\cdots&A\e......
  • AtCoder Regular Contest 134 E Modulo Nim
    洛谷传送门AtCoder传送门It'sallMAGIC这种题目一般先考虑局面要满足什么条件能必胜,然后根据这个性质来计数。如果把黑板上的数写成一个集合\(S\),那么:\(\varnothing\)为必胜态,\(\{1\},\{2\}\)显然为必败态,打表发现其他单元素集合都为必胜态;如果\(\existsx\inS,x......
  • AtCoder Beginner Contest 242
    A-T-shirt#include<bits/stdc++.h>usingnamespacestd;int32_tmain(){doublea,b,c,x; cin>>a>>b>>c>>x; if(x<=a)cout<<"1.000000000000"; elseif(x>b)cout<<&qu......
  • AtCoder Beginner Contest 285(B,D,E,F)
    AtCoderBeginnerContest285(B,D,E,F)B(暴力,非二分)B这道题其实很简单,但是我在\(vp\)的过程,有了一个错误的认识,纠正一下那就是,我把这个当成了一个二分题,并且还有点坚定不移,后来细想,发现不对二分,适用于那种边界分明的那种题(左边一定是符合条件,右边一定符合条件,也可表达为线性......
  • [AtCoder-AT_ABC108_B]题解(C++)
    PartIPreface原题目(Luogu)原题目(AtCoder)PartIISketchPartIIIAnalysis观察这道题,我们很容易想到,必须推导出\(x1,y1,x2,y2\)与\(x3,y3,x4,y4\)之间的关系。我们观察下图。可以发现:\(\begin{aligned}\begin{cases}x3=x2-(y2-y1)\\y3=y2+(x2-......
  • AcWing 1209. 带分数
    1-暴力解法思考1:暴力列举出1~9的全排列,之后再将这些数字按照一定规则相加,最后将结果与n比较。全排列好写,但相加的规则不好写,而且太暴力了,估计会超时。/*AcWing1209.带分数00.最暴力的写法1.枚举全排列2.枚举位数(枚举a和b,可算出c)3.直接算出n,判断等......
  • AtCoder Regular Contest 131 E Christmas Wreath
    洛谷传送门AtCoder传送门不难猜想有解充要条件为\(n\ge5\)且\(\frac{n(n-1)}{2}\bmod3=0\)。发现如果钦定一个点的出边都为同一种颜色,那么条件\(2\)一定满足。那么题目等价于把\(\{0,1,...,n-1\}\)分成\(3\)组使得每组的和相等。这个东西可以随便dp做,也不......
  • 209. 长度最小的子数组
     分析:这题是找满足和大于等于target的最短数组有点小问题,想用双指针做,但是写得有点糅杂了最后一组案例时间超了最后借鉴了一下题解写出来代码:1classSolution(object):2defminSubArrayLen(self,target,nums):3"""4:typetarget:int......
  • AtCoder Regular Contest 131 D AtArcher
    洛谷传送门AtCoder传送门观察可以发现:使每支箭的距离都为\(D\)一定不劣;每支箭坐标一定为整数;设最左边的箭坐标为\(x\),那么\(x\)太小时可以把最左边的箭移到最右边,\(x\)太大时可以把最右边的箭移到最左边。计算可得\(x\)的最优取值范围为\(x\in[-\left\lfloor\fr......