首页 > 其他分享 >AtCoder Beginner Contest 289(E,F)

AtCoder Beginner Contest 289(E,F)

时间:2023-05-30 21:55:08浏览次数:59  
标签:AtCoder sx return Beginner int dis 289 include define

AtCoder Beginner Contest 289(E,F)

E(dijkstra)

E

这个题的大意就是有两个人,一个人在点\(1\),一个人在点\(n\),现在两个人要同时走(题目给出了点和边,还有每一个点的颜色),但是他们的下一步要到的点需要是颜色不同的,问\(1\)点出发的和\(n\)点

出发的同时达到对方的起点的最短路径时哪个

一开始觉得好复杂呀,还有考虑颜色,会不会超时

其实不用担心这个,\(n\)和\(m\)都不是很大,\(n\)为\(2e3\),我们可以定义状态为两个人的不同位置,假如此时是\(x,y\),一人在点\(x\),一人在点\(y\),那我们任意组合这两个点可达的点,对于颜色不同的满足条件的可以考虑

然后后面的就是\(djkstra\)了

我很多时候都害怕超时而放弃某一个想法,希望下一次可以多试试,还有就是我自己的时间复杂度也不太会计算

#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 int maxn=2e3+10;
const int mod=998244353;
int t,n,m;
vector<int>g[maxn];
int col[maxn];
struct node
{
    int l,r,dis;
    friend bool operator < (const node x,const node y)
    {
        return x.dis>y.dis;
    }
};
void init()
{
    for (int i=1;i<=n;i++)
    {
        g[i].clear();
    }
}
int dijkstra()
{
    priority_queue<node>q;
    vector<vector<int>>dis(n+1,vector<int>(n+1,inf));
    vector<vector<bool>>vis(n+1,vector<bool>(n+1,false));
    dis[1][n]=0;
    q.push({1,n,dis[1][n]});
    while (!q.empty())
    {
        auto [l,r,d]=q.top();
        q.pop();
        if(l==n&&r==1)
        {
            return d;
        }
        if(vis[l][r]) continue;
        vis[l][r]=true;
        for (auto x:g[l])
        {
            for (auto y:g[r])
            {
                if(col[x]!=col[y])
                {
                    if(dis[x][y]>d+1)
                    {
                        dis[x][y]=d+1;
                        q.push({x,y,d+1});
                    }
                }
            }
        }
    }
    return -1;
}
void solve()
{
    cin>>n>>m;
    for (int i=1;i<=n;i++)
    {
        cin>>col[i];
        g[i].clear();
    }
    for (int i=1;i<=m;i++)
    {
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    int ans=dijkstra();
    cout<<ans<<"\n";
    return ;
}
signed main ()
{
    cin>>t;
    while (t--)
    {
        solve();
    }
    system ("pause");
    return 0;
}

F (计算几何)

F

给出我们两个点\(sx,sy\)和\(tx,ty\),还有一个矩形\(a<=x<=b\),\(c<=y<=d\),就是\(x\)的范围是从\(a\)到\(b\),\(y\)的范围是\(c\)到\(d\),我们可以在这一块矩形里面任意选择一个点,把\(sx,sy\)变成一个以我们选择的点作为对称中心变成该点的对称位置,问我们可以怎么选择把\(sx,sy\)变成\(tx,ty\),如果不可以,输出\(-1\)

首先,我们要知道点对称变换的公式

如\(sx,sy\)以\(x,y\)对称的位置是\(xx,yy\),公式如下

\[xx=2\times x-sx\\yy=2\times y-sy \]

扩展学习

这里面有一个规律

当我们只看一维的时

如果一开始把\(sx,sy\)对\(x,y\)进行对称操作,然后再对\(x+1,y\)进行操作时,\(sx\)变成了\(sx+2\)(可以自己画着试一试)

反过来,如果一开始把\(sx,sy\)对\(x+1,y\)进行对称操作,然后再对\(x,y\)进行操作时,\(sx\)变成了\(sx-2\)

而且,对于二维坐标,这个是独立而互不影响的,所以每一次我们都可以对坐标进行一个加二或者减二的操作

那么我们要求坐标和目标坐标的距离是偶数,也就是他们的奇偶性相同即可

这是对于存在\(x\)和\(x+1\)操作的

还有一种情况就是\(a\)和\(b\)是一样的,那么就不能进行\(x+1\)的操作了

那么就只有\(a\)刚好是中点或者\(sx\)(只需一次操作)和\(tx\)是一样的(这样的话就根本不需要操作了)才可能成功

所以,对于不能进行\(x+1\)的那一步操作的,我们先进行一次操作(如果有必要的话),如果还是不行,那么直接输出\(No\)

后面就是排除了前面的特殊情况,一定是可以到达的情况了,我们就只用考虑让\(sx\)等于\(tx\),\(sy\)等于\(ty\)就好了

#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 int maxn=2e3+10;
const int mod=998244353;
struct point
{
    int x,y;
}s,t;
int a,b,c,d;
vector<pair<int,int>>ans;
bool ok(int i,int j,int l,int r)
{
    //  bool ok0 = ((i ^ j) % 2 == 0 && (l != r || (i == j|| l + r == i + j)));
    //  return ok0;
     if(i==j) return true;
    if((i&1)!=(j&1)) return false;
    if(l==r)
    {
        if(i+j==l+r)
        {
            return true;
        }
        return false;
    }
    return true;
}
void update(int x,int y)
{
    s.x=2*x-s.x;
    s.y=2*y-s.y;
    ans.push_back({x,y});
    return ;
}
signed main ()
{
    cin>>s.x>>s.y>>t.x>>t.y;
    cin>>a>>b>>c>>d;
    if(!ok(s.x,t.x,a,b)||!ok(s.y,t.y,c,d))
    {
        cout<<"No\n";
        system ("pause");
        return 0;
    }
    if(a==b&&s.x!=t.x)//只变一次,x可能会变,y也可能会变
    {
        update(a,c);
    }
    if(c==d&&s.y!=t.y)
    {
        update(a,c);
    }
    //都变完一次的情况,最后再来考虑会导致不一样的情况
    if(s.x!=t.x&&a==b)
    {
        cout<<"No\n";
        system ("pause");
        return 0;
    }
    if(s.y!=t.y&&c==d)
    {
        cout<<"No\n";
        system ("pause");
        return 0;
    }
    while (s.x<t.x)
    {
        update(a,c);
        update(a+1,c);
    }
    while (s.x>t.x)
    {
        update(a+1,c);
        update(a,c);
    }
    while (s.y<t.y)
    {
        update(a,c);
        update(a,c+1);
    }
    while (s.y>t.y)
    {
        update(a,c+1);
        update(a,c);
    }
    cout<<"Yes\n";
    for (auto [x,y]:ans)
    {
        cout<<x<<" "<<y<<"\n";
    }
    system ("pause");
    return 0;
}

标签:AtCoder,sx,return,Beginner,int,dis,289,include,define
From: https://www.cnblogs.com/righting/p/17444592.html

相关文章

  • AtCoder Beginner Contest 303
    A-SimilarString(abc303a)题目大意给定两个字符串,问这两个字符串是否相似。两个字符串相似,需要每个字母,要么完全相同,要么一个是1一个是l,要么一个是0一个是o解题思路按照题意模拟即可。可以将全部1换成l,全部0换成o,再判断相等。神奇的代码#include<bits/stdc++.h>us......
  • AtCoder Regular Contest 153 D Sum of Sum of Digits
    洛谷传送门AtCoder传送门又浪费一道好题我首先想的是,\(x\)显然最优取某些\(a_i\)往前进位时的值。然后就误以为\(x\)的取值是\(O(n\log_{10}V)\)的了……既然没发现什么性质,那就直接dp吧!设\(f_{d,i}\)为从低到高前\(d\)位,所有\(a_i\)进位之和为\(i\)。然......
  • ROS2-Beginner:CLI tools-1、环境配置
    1、环境配置目标:本教程告诉读者怎样准备ROS2环境背景:ROS2依赖于使用shell环境组合工作空间的概念,“工作区”是一个ROS术语,表示您使用ROS2进行开发的系统上的位置。ROS2的核心工作空间称为底层(underlay)。后续的局部工作空间称为覆盖(overlays)。当使用ROS2进行开发时,通常会同......
  • AtCoder Regular Contest 161
    PrefaceARC战俘闪总出列这场一上来就感觉状态不太对,先是A顺序敲反WA了一发,然后C题看到秒出一个贪心然后也WA了看一眼榜发现D过的比C多,然后跑去把D写了,中间还偷偷挂了两发最后50min回去沉淀C题,结果换了两种写法都还是一样的挂,后面发现想法还是有纰漏总结:彩笔A-MakeM考虑......
  • AtCoder Regular Contest 148 E ≥ K
    洛谷传送门AtCoder传送门是一道不错的计数。考察合法序列的形态,容易发现:不能出现两个\(<\frac{k}{2}\)的数相邻;如果\(x<\frac{k}{2},y\ge\frac{k}{2}\),那么\(|y-\frac{k}{2}|\ge|x-\frac{k}{2}|\)。考虑不直接排列,而是按照一定的顺序插入。考虑按照\(|x......
  • AtCoder Beginner Contest 290(D,E)
    AtCoderBeginnerContest290(D,E)D(思维,数学)D这个题的大意就是我们需要标记\(n\)个位置,他是这样标记的,一开始有一个初始值为\(0\)的\(x\),第一个标记的是\(0\)位置,然后下一步,我们把\(x\)变成\((x+d)modn\),如果这个位置没有被标记,否则把\(x\)变成\((x+1)modn\),这个是没有......
  • AtCoder Regular Contest 161 E Not Dyed by Majority (Cubic Graph)
    洛谷传送门AtCoder传送门给构造题提供了一种新的思路。如果答案占总方案数的比较大,可以考虑随机化。例如本题,考虑随机化,难点变成判断一个方案是否可行。考虑2-SAT,如果一个点是\(\text{B}\),那么对于这个点的边,有一条边的另一个端点是\(\text{W}\),那么其他两个都是\(\text{......
  • AtCoder Beginner Contest 303 题解 A - E
    A-SimilarString题目大意忽略0和o的差别以及1和l的差别比较两个字符串。解题思路可以硬求,直接写个超长的if判断一下。可以对两个字符串进行修改,0都换成o,1都换成l,然后直接比较两个字符串。ACCode硬求#include<iostream>#include<algorithm>#include<cstring>#i......
  • AtCoder Beginner Contest 303 G Bags Game
    洛谷传送门AtCoder传送门经典题,考虑区间dp,\(f_{l,r}\)表示只考虑\([l,r]\)区间,先手得分减后手得分最大值。对于第一种操作直接\(f_{l,r}\gets\max(a_l-f_{l+1,r},a_r-f_{l,r-1})\),第二种操作,考虑枚举\([l,r]\)长为\(r-l+1-B\)的子段,即可转移。第三种操......
  • AtCoder Beginner Contest 298(D,F)
    AtCoderBeginnerContest298(D,F)D(思维,模拟,快速幂)D大意是最初有一个数字\(1\),然后进行\(q\)个操作有三种操作\(1\),输入\(1,x\),在原来的数字后面添加一个尾数,例如原本的数是\(12\),输入了\(15\),数字变成了\(125\)\(2\),输入\(2\),把原来的数字第一位数删除,例如原本的数是......