AtCoder Beginner Contest 258
AtCoder Beginner Contest 258
B
题目大意是给你一个表格(nXn),每一个位置上有一个数,我们要从某一个位置出发,走n-1步,将每一步得到的数都连在一起,求出连在一起的最大值,(第一步确定方向,后面的n-2步都要和第一步方向相同)
这个题我大意了(我以为是四个方向)
n<=10,那么我们可以直接取max,一个一个找,不会超时
注意边界的处理
#include <iostream>
#include <string>
using namespace std;
#define int long long
const int maxn=20;
string s[maxn];
int n;
int dx[9]={0,0,-1,1,-1,-1,1,1};
int dy[9]={-1,1,0,0,1,-1,-1,1};
int ans=0;
int dfs(int x,int y)
{
for (int k=0;k<8;k++)
{
int res=s[x][y]-'0';
for (int i=2;i<=n;i++)
{
int ttx=x+dx[k];
int tty=y+dy[k];
if (ttx>n)
{
ttx=1;
}
if (ttx==0)
{
ttx=n;
}
if (tty>n)
{
tty=1;
}
if (tty==0)
{
tty=n;
}
res=res*10+(s[ttx][tty]-'0');
x=ttx,y=tty;
}
ans=max(ans,res);
}
return ans;
}
signed main ()
{
cin>>n;
int posx=0,posy=0;
for (int i=1;i<=n;i++)
{
cin>>s[i];
s[i]=" "+s[i];
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
ans=min(ans,dfs(i,j));
}
}
cout<<ans<<'\n';
system ("pause");
return 0;
}
C
题目大意是给你一个长度为n的字符串s,下面有n个操作,有两种操作类型,输入一个op,一个x
op=1,那么就把后面的x个字符移到前面来
op=2,那么我们需要输出第x个字符
这个用直接模拟的话会超时
我们可以不改变s,只是改变第一个字符的位置pos
如果要把x个字符移动到前面,那么第一个字符的位置就要加上x(pos+=x)
对于输出x个字符
我们可以直接输出第(x-pos+n)%n个字符(假如x=pos,那么我们输出的就是第一个,x=pos+1,那么就是第2个),注意字符的第1个是s[0],所以我们需要先减1
#include <iostream>
#include <string>
using namespace std;
string s;
int n,m;
int main ()
{
cin>>n>>m;
cin>>s;
int st=0;
while (m--)
{
int op,x;
cin>>op>>x;
if (op==1)
{
st+=x;
st%=n;
}
else
{
x--;
int pos=(x-st+n)%n;
cout<<s[pos]<<'\n';
}
}
system ("pause");
return 0;
}
D
这个给我们一个x,还有n个a,b,我们必须从1开始,对于第一次使用,必须用到a,b(价值为1),下一次可以找下一个a,b,或者是还是使用这一个,这一次不是使用的第一次,那么我们只需要使用b(价值为1),我们需要知道要价值达到x的最sum
我这个差一点了,就是没有考虑到x小于n的情况(下次一定要注意)
#include <iostream>
using namespace std;
const int maxn=5e5+10;
#define int long long
int f[maxn];
int n,x,a[maxn],b[maxn];
signed main ()
{
cin>>n>>x;
for (int i=1;i<=n;i++)
{
cin>>a[i]>>b[i];
}
int sum=0;
int ans=0;
for (int i=1;i<=n&&i<=x;i++)
{
sum+=a[i]+b[i];
f[i]=sum+(x-i)*b[i];//如果没有考虑到x小于n,那么会出现负数
if (i==1)
{
ans=f[i];
}
else
{
ans=min(ans,f[i]);
}
}
// ans++;
cout<<ans<<'\n';
system ("pause");
return 0;
}
E
这个题大意是从1到n,然后到1,然后到n这样一个循环,我们每一次都会选择若干个数,(按顺序),如果大于x(题目给出),那么我们就需要另外一个新的集合了,后面有q次询问,问第几个集合里面有几个数
这个我们可以猜测会出现循环(其实我还是有点不太明白为什么不会超时,哎,)
我们只要找出这一个集合以这个位置为第一个放入的数,后面还出现了以这一个位置为第一个放入的数,那么此时就是出现了循环,后面的就不需要找了
对于我们要找从i到j这一段刚好是大于等于x,这里用了前缀和和二分
具体看代码
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
#define int long long
const int maxn=2e5+10;
int n,w[maxn],x,q;
int vis[maxn],sum[maxn];
int cnt,s,t;
int len;
signed main ()
{
vector<int>f;
f.push_back(0);
cin>>n>>q>>x;
for (int i=1;i<=n;i++)
{
cin>>w[i];
sum[i]=sum[i-1]+w[i];
}
int now=1;
while (!vis[now])
{
vis[now]=++cnt;
if (sum[n]-sum[now-1]>=x)
{
int pos;//下一个
pos=lower_bound(sum+1,sum+1+n,sum[now-1]+x)-sum;//找到的sum[pos]-sum[now-1]>=x
f.push_back(pos-now+1);//这一次放入了几个数
//cout<<pos-now+1<<' ';
now=pos+1;//下一个
if (now==n+1) now=1;
}
else //这个情况是还不够,还需要1到pos的数,若干个n个数,还要pos个数
{
int tmp=x-(sum[n]-sum[now-1]);
int res=n-now+1+(tmp/sum[n])*n;
tmp%=sum[n];
int pos=lower_bound(sum+1,sum+1+n,tmp)-sum;
res+=pos;
f.push_back(res);
now=pos+1;
if (now==n+1) now=1;
}
if (vis[now])//这个时候就出现了循环
{
s=vis[now],t=cnt;//s是开始进入循环的点,前面的不是循环里面的
len=t-s+1;//len为周期
break;
}
}
//cout<<'\n';
while (q--)
{
int x;
cin>>x;
if (x<=cnt)//如果有答案,就直接输出
{
cout<<f[x]<<'\n';
}
else //否则利用循环
{
int p=x-cnt;//多出的长度
p%=len;
if (p==0) p=len;
cout<<f[s-1+p]<<'\n';//p只是循环里的第几个,而f里是s-1后面才出现的循环
}
}
system ("pause");
return 0;
}
F
这个题目我理解了好久
就是有一个sx,sy,ex,ey,我们要从sx,sy到ex,ey,对于每一步,(可以有四个方向,上下左右),而对于x或者y是b的倍数的时候走这一段需要1s,其他的我们需要ks
我们就是要找最少的时间
有一种最直接的方式,
直接走,不走高速dis=(abs(sx-ex)+abs(sy-ey))*k
还有,就是先到高速,(起点终点都到高速),到哪一个高速呢,我们有四个方向,到上面的高速,下面的高速,左面的高速,右面的高速
对于两个点的高速都是同一个方向的(都是横向,竖向的)
我们要这几种走法
对于是不同方向的
我们直接这样走
对于不同的走法,我们取Min
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
#define int long long
#define min4(x,y,z,q) min(x,min(y,min(z,q)))
const int maxn=2e5+10;
int b,k,sx,sy,ex,ey;
vector<pair<int,int>> fun(int x,int y)//四个方向最近的高速
{
vector<pair<int,int>>a;
a.push_back({x,y+b-(y%b)});
a.push_back({x,y-(y%b)});
a.push_back({x+b-(x%b),y});
a.push_back({x-(x%b),y});
return a;
}
int cal(int x,int y,int xx,int yy)
{
int res=2e18;
bool flag=false;
if(x/b==xx/b&&y%b==0&&yy%b==0)//y都是高速
{
flag=true;
int tmp=abs(y-yy)*k+abs(x-xx);
res=min(res,tmp);
tmp=abs(y-yy)+ (b-x%b+b-xx%b);
res=min(res,tmp);
tmp=tmp=abs(y-yy)+ (x%b+xx%b);
res=min(res,tmp);
}
if(y/b==yy/b&&x%b==0&&xx%b==0)//x都是高速
{
flag=true;
int tmp=abs(x-xx)*k+abs(y-yy);
res=min(res,tmp);
tmp=abs(x-xx)+ (b-y%b+b-yy%b);
res=min(res,tmp);
tmp=tmp=abs(x-xx)+ (y%b+yy%b);
res=min(res,tmp);
}
if (!flag)//一个是x,一个是y
{
int tmp=abs(x-xx)+abs(y-yy);
res=min(res,tmp);
}
return res;
}
void solve()
{
cin>>b>>k>>sx>>sy>>ex>>ey;
vector<pair<int,int>>s=fun(sx,sy);
vector<pair<int,int>>g=fun(ex,ey);
int ans=(abs(sx-ex)+abs(sy-ey))*k;
for (int i=0;i<4;i++)
{
int tx=s[i].first;
int ty=s[i].second;
for (int j=0;j<4;j++)
{
int ttx=g[j].first;
int tty=g[j].second;
int tmp=(abs(tx-sx)+abs(ty-sy)+abs(ttx-ex)+abs(tty-ey))*k+cal(tx,ty,ttx,tty);
ans=min(ans,tmp);
}
}
cout<<ans<<'\n';
return ;
}
signed main ()
{
int t;
cin>>t;
while (t--)
{
//cout<<t<<"next\n";
solve();
}
system ("pause");
return 0;
}
G
这个题是还是一个表格,ai,j代表i,j是否连通,(1代表连通,0代表不连通)
我是要找出i,j,k都互相连通的数量
这个我试过一个一个找,不过超时了
但是这个如果用bitset来写真的很好,因为bitset可以直接看成二进制进行&运算,如果两个都是1,那么说明那一个既可以到达i,又可以到达j(注意不要把重复的加进去,和本身),然后我们还可以直接求出1的数量,真是太好用了
#include <iostream>
#include <bitset>
#include <vector>
#include <string>
using namespace std;
#define int long long
const int maxn=3e3+10;
int ans;
bitset<3000>g[maxn];
string s;
int n;
signed main ()
{
cin>>n;
for (int i=1;i<=n;i++)
{
string s;
cin>>s;
s=" "+s;
for (int j=i+1;j<=n;j++)//我们直接存后面的,前面的不保存,不会重复
{
if (s[j]=='1')
{
g[i][j]=1;
}
}
}
for (int i=1;i<=n;i++)
{
for (int j=i+1;j<=n;j++)
{
if (g[i][j])
{
ans+=(g[i]&g[j]).count();
}
}
}
cout<<ans<<'\n';
system ("pause");
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!