abc258_a

题目翻译

Atcoder 的 ABC 一般在东京时间 $\tt{21:00}$ 开始,持续 $100$ 分钟。

问开始后 $x$ 分钟后,是东京时间几点?

注意时和分有前导零。

题目思路

随便写写,特判前导零,或者用 printf

AC 代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int k;
    cin>>k;
    cout<<21+k/60<<":";
    if(k%60<10)cout<<0<<k%60;
    else cout<<k%60;
    cout<<endl;
    return 0;
}

abc258_b

题目翻译

有一个 $n\times n$ 的棋盘,你可以从某个点出发,向上、下、左、右、上左、上右、下左、下右八个方向走 $n-1$ 次。

PS:这里写左上之类的是不是读起来更流畅。

其中,你当前走这条路的收益,就是 $n$ 个点上的数字按经过顺序组成的数。

问收益最大是多少。

题目思路

$8$ 个方向扫。

可以直接写,也可以写 $dx[]=...,dy[]=...$。

题不在难,码量大则毒瘤。

PS:我算什么品种的制杖,因为 stoi 参数爆 int 最后过才 B。

AC 代码

#include<bits/stdc++.h>
using namespace std;
char a[100][100];
int n;
string U(int i,int j)
{
    int x=n;
    string ret="";
    for(;x>=1;i--,x--)
    {
        if(i==0)i=n;
        ret+=a[i][j];
    }
    return ret;
}
string D(int i,int j)
{
    int x=n;
    string ret="";
    for(;x>=1;i++,x--)
    {
        if(i==n+1)i=1;
        ret+=a[i][j];
    }
    return ret;
}
string L(int i,int j)
{
    int x=n;
    string ret="";
    for(;x>=1;j--,x--)
    {
        if(j==0)j=n;
        ret+=a[i][j];
    }
    return ret;
}
string R(int i,int j)
{
    int x=n;
    string ret="";
    for(;x>=1;j++,x--)
    {
        if(j==n+1)j=1; 
        ret+=a[i][j];
    }
    return ret;
}
string UL(int i,int j)
{
    int x=n;
    string ret="";
    for(;x>=1;i--,j--,x--)
    {
        if(i==0)i=n;
        if(j==0)j=n;
        ret+=a[i][j];
    }
    return ret;
}
string UR(int i,int j)
{
    int x=n;
    string ret="";
    for(;x>=1;i--,j++,x--)
    {
        if(i==0)i=n;
        if(j==n+1)j=1;
        ret+=a[i][j];
    }
    return ret;
}
string DL(int i,int j)
{
    int x=n;
    string ret="";
    for(;x>=1;i++,j--,x--)
    {
        if(i==n+1)i=1;
        if(j==0)j=n;
        ret+=a[i][j];
    }
    return ret;
}
string DR(int i,int j)
{
    int x=n;
    string ret="";
    for(;x>=1;i++,j++,x--)
    {
        if(i==n+1)i=1;
        if(j==n+1)j=1;
        ret+=a[i][j];
    }
    return ret;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin>>a[i][j];
        }
    }
    long long ans=-1;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            ans=max(ans,stoll(U(i,j)));
            ans=max(ans,stoll(D(i,j)));
            ans=max(ans,stoll(L(i,j)));
            ans=max(ans,stoll(R(i,j)));
            ans=max(ans,stoll(UL(i,j)));
            ans=max(ans,stoll(UR(i,j)));
            ans=max(ans,stoll(DL(i,j)));
            ans=max(ans,stoll(DR(i,j)));
        }
    }
    cout<<ans<<endl;
    return 0;
}

再赋另一种写法。

by @Factorio

#include <bits/stdc++.h>
using namespace std;
int n;
string s[10], z;
int dx[] = {1, 1, 0, -1, -1, -1, 0, 1};
int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};
int main()
{
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        cin >> s[i];
    }
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            for (int k = 0; k < 8; k++)
            {
                string t;
                for (int l = 0; l < n; l++)
                {
                    t += s[(i + dx[k] * l + n) % n][(j + dy[k] * l + n) % n];
                }
                z = max(z, t);
            }
        }
    }
    cout << z << endl;
    return 0;
}

abc258_c

题目翻译

有长度为 $n$ 的字符串 $s$,有 $q$ 次操作。

操作 1 x,把 $s$ 的后 $x$ 个字符挪到前面。

操作 2 x,输出 $s$ 的第 $x$ 位。

题目思路

统计操作 1 x,$x$ 的和共有多少(下文与代码统称 $c$),不可以每次模拟。

统计出 $c$,看一下 $c \bmod n$ 和操作 2 x 的大小关系。

$\bmod n$ 是因为可能有移了超过 $n$ 次。

AC 代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n,q,c=0;
    string s;
    cin>>n>>q>>s;
    while(q--)
    {
        int o;
        cin>>o;
        if(o==1)
        {
            int x;
            cin>>x;
            c+=x;
            c%=n;
        }
        else
        {
            int y=n-c;
            int x;
            cin>>x;
            if(x<=c)
            {
                cout<<s[y-1+x]<<endl;
            }
            else
            {
                x-=c;
                cout<<s[x-1]<<endl;
            }
        }
    }
    return 0;
}

abc258_d

题目翻译

有 $n$ 个关卡,第 $i$ 关,第一次通过需要 $a_i+b_i$ 时间,之后只需 $b_i$ 时间。

只有通过 $i-1$ 的关卡才可游玩 $i$ 关。

问过 $x$ 关,至少需要多少时间。

题目思路

我们最后一定是重复过最后通过的一关

然后枚举最后打哪一关。

AC 代码

#include<bits/stdc++.h>
typedef unsigned long long ll;
using namespace std;
ll a[200005],b[200005],c[200005];
int main()
{
    ll n,x;
    cin>>n>>x;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i]>>b[i];
        c[i]=c[i-1]+a[i]+b[i];
    }
    ll ans=9e18;
    for(int i=1;i<=n;i++)
    {
        ll y=i-1;
        if(y>=x)
        {
            ans=min(ans,c[i-1]);
        }
        else
        {
            ll z=x-y,cnt=c[i-1];
            z--;
            cnt+=a[i]+b[i];
            cnt+=z*b[i];
            ans=min(ans,cnt);
        }
    }
    cout<<ans<<endl;
    return 0;
}
最后修改:2023 年 04 月 20 日
v我50吃疯狂星期四