每一年都奔走在自己热爱里

没有人是一座孤岛,总有谁爱着你

AtCoder Beginner Contest 272(D,E)

AtCoder Beginner Contest 272(D,E)

D

D

这个题最主要的是需要找出有哪些移动的距离

对于题目给出的m,我们的移动过程可以是(iii)2+(jjj)2=m

这样的话,我们可以对m分解成两个平方数ab,然后对于这个ab的分配,一共有8种方向,(没有规定a一定是x方向上的,也没有规定只能往前走)

然后就bfs即可

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=400+10;
#define int long long 
int n,m;
int dis[maxn][maxn];
bool vis[maxn][maxn];
int dx[maxn];
int dy[maxn];
int cnt;
void get()
{
    for(int i=0;i<=n;i++)
        {
            for(int j=i;j<=n;j++)
            {
                if(i*i+j*j==m)
                {
                    dx[++cnt]=i,dy[cnt]=j;
		            dx[++cnt]=i,dy[cnt]=-j;
		            dx[++cnt]=-i,dy[cnt]=j;
		            dx[++cnt]=-i,dy[cnt]=-j;
		            dx[++cnt]=j,dy[cnt]=i;
		            dx[++cnt]=j,dy[cnt]=-i;
		            dx[++cnt]=-j,dy[cnt]=i;
		            dx[++cnt]=-j,dy[cnt]=-i;
                }
            }
        }
    return ;
}
void bfs()
{
    queue<pair<int,int>>q;
    q.push({1,1});
    vis[1][1]=true;
    while (!q.empty())
    {
        int x=q.front().first;
        int y=q.front().second;
        q.pop();
        for (int d=1;d<=cnt;d++)
        {
            int tx=x+dx[d];
            int ty=y+dy[d];
            if (tx>n||ty>n||tx<=0||ty<=0) continue;
            if (vis[tx][ty]) continue;
            vis[tx][ty]=true;
            dis[tx][ty]=dis[x][y]+1;
            q.push({tx,ty});
        }
    }
    return ;
}
signed main ()
{
    cin>>n>>m;
    get();
    memset(dis,-1,sizeof(dis));
    dis[1][1]=0;
    vis[1][1]=true;
    bfs();
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=n;j++)
        {
            cout<<dis[i][j]<<" ";
        }
        cout<<'\n';
    }
    system ("pause");
    return 0;
}

E

E

这个题呢就是给你n个数,我们会进行m轮操作,每一轮操作ai都会变成ai+i,对于每一轮操作后得到的n个数,我们需要知道这n个数的mex

对于mex,我们可以知道负数是对mex有任何影响的,还有大于n的数也一定是没有影响的(要想mexn+1,至少需要n+1个数

那么对于每一个数,我们需要记录的就只能是小于等于n的非负数

mex的过程,就是一一判断1mex1这一段之间的数是否存在,我们直接用map表示第x次操作后有哪些数字存在

那么对于那些小于0的数,我们首先要找到他大于等于0的最小操作,然后再一个一个操作地记录

然后具体的就看代码吧

#include <iostream>
#include <algorithm>
#include <map>
#include <algorithm>
using namespace std;
const int maxn=2e5+10;
#define int long long 
int n,m;
int a[maxn];
map<int,bool>vis[maxn];
signed main ()
{
    cin>>n>>m;
    for (int i=1;i<=n;i++)
    {
        cin>>a[i];
        int tim=0;
        if (a[i]<0)
        {
           
            int now=-1*a[i];
            int  k=now/i+(now%i!=0);//>=0需要的次数 
			tim=k-1;
        }
        for (int j=tim+1;j<=m&&(a[i]+i*j)<=n;j++)
        {
            vis[j][a[i]+i*j]=true;
        }
    }
    for (int i=1;i<=m;i++)
    {
        for (int j=0;j<=n;j++)
        {
            if (!vis[i][j])
            {
                cout<<j<<"\n";
                break;
            }
        }
    }
    system ("pause");
    return 0;
}

F

不会写

posted @   righting  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示