2022.5.10

AtCoder Beginner Contest 250

A - Adjacent Squares

判断一下四个方向有无格子即可

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0};
int n, m;
bool check(int x,int y)
{
    return x >= 1 && x <= n && y >= 1 && y <= m;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int x, y;
    cin >> n >> m >>x >> y;
    int cnt = 0;
    for (int i = 0; i < 4;i++)
    {
        int xx = dx[i] + x, yy = dy[i] + y;
        if(check(xx,yy))
            cnt++;
    }
    cout << cnt;
    return 0;
}

B - Enlarged Checker Board

当时看样例想到的奇怪的思路:可以先把第一个图形敲出来,然后再得出它的相反的图形,最后输出n次即可

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e5+10,INF=1e9;
char s[100][100],ss[100][100];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n, a, b;
    cin >> n >> a >> b;
    for (int i = 1; i <= a;i++)
    {
        int cnt = 0;
        int f = 1;
        for (int j = 1; j <= n*b;j++)
        {
            cnt++;
                if(f)
                    s[i][j] = '.';
                else
                    s[i][j] = '#';
                if(cnt==b)
                {
                    cnt = 0;
                    f ^= 1;
                }
        }
    }
    for (int i = 1; i <= a;i++)
    {
        for (int j = 1; j <= n*b;j++)
        {
            if(s[i][j]=='.')
            {
                ss[i][j] = '#';
            }
            else
                ss[i][j] = '.';
        }
    }
    for (int i = 1; i <= n;i++)
    {
        for (int j = 1; j <= a;j++)
        {
            for (int k = 1; k <= n*b;k++)
            {
                if(i&1)
                    cout << s[j][k];
                else
                    cout << ss[j][k];
            }
            cout << '\n';
        }
    }
        return 0;
}

C - Adjacent Swaps

利用map存储该数的位置,交换的过程中同时更新map对应的位置,特判一下等于n的情况即可。需要注意要提前把mp[x]的位置保存下来,否则swap之后会发生改变就不是原来的x了。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<map>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=2e5+50,INF=1e9;
int a[N];
map<int, int> mp;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n, k;
    cin >> n >> k;
    for (int i = 1; i <= n;i++)
    {
        a[i] = i;
        mp[i] = i;
    }
    for (int i = 1; i <= k;i++)
    {
        int x;
        cin >> x;
        if(mp[x]==n)
        {
            int left = a[mp[x] - 1];
            swap(a[mp[x]], a[mp[x] - 1]);
            mp[left]++;
            mp[x]--;
        }
        else
        {
            int right = a[mp[x] + 1];
            swap(a[mp[x]], a[mp[x] + 1]);
            mp[right]--;
            mp[x]++;
        }
    for (int i = 1; i <= n;i++)
    {
        cout << a[i] << " \n"[i==n];
    }
        return 0;
}

D - 250-like Number

n为1e18,观察到q3次方不会超过1e18,即q不会超过1e6,所以考虑预处理出1e6以内的质数,枚举从1-1e6的素数,此时p为min(q-1,n/q/q/q)以内的质数,可以前缀和预处理出p的个数也可以直接暴力。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N=1e6+10,INF=1e9;
bool isp[N];
ll sum[N];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    for (int i = 1; i <= 1e6;i++)
    {
        isp[i] = 1;
    }
    for (int i = 2; i <= 1e6;i++)
    {
        if(isp[i])
        {
            for (int j = i + i; j <= 1e6;j+=i)
                isp[j] = 0;
        }
    }
    // for (int i = 2; i <= 1e6;i++)
    // {
    //     sum[i] = sum[i - 1] + isp[i];
    // }
    ll n;
    ll ans = 0;
    cin >> n;
    for (int i = 2; i <= 1e6;i++)
    {
        if(isp[i])
        {
            //ans += sum[min((ll)i - 1, n / i / i / i)];
            ll res = min((ll)i - 1, n / i / i / i);
            for (int j = 2; j <= res;j++)
            {
                if(isp[j])
                    ans++;
            }
        }
    }
    cout << ans;
    return 0;
}

E - Prefix Equality

补题时想到了哈希,但是由于不熟练只知道思路。可以考虑给每一个数赋一个随机值,学到了新方法mt19937(0),利用ull存储64位,同时利用set来做到去重,mp判断是否已经被赋过随机数,最后只需要判断ha[a]是否等于hb[b]即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<random>
#include<set>
#include<map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int N=2e5+10,INF=1e9;
int a[N],b[N];
ull ha[N], hb[N];
map<int, ull> mp;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    mt19937 ran(0);
    int n;
    set<int> sa,sb;
    cin>>n;
    for (int i = 1; i <= n ;i++)
    {
        cin >> a[i];
    }
    for (int i = 1; i <= n;i++)
    {
        cin >> b[i];
    }
    for (int i = 1; i <= n;i++)
    {
        if(!mp[a[i]])
        {
            mp[a[i]] = ran();
        }
        ha[i] = ha[i - 1];
        if(!sa.count(a[i]))
        {
            ha[i] += mp[a[i]];
            sa.insert(a[i]);
        }

        if(!mp[b[i]])
        {
            mp[b[i]] = ran();
        }
        hb[i] = hb[i - 1];
        if(!sb.count(b[i]))
        {
            hb[i] += mp[b[i]];
            sb.insert(b[i]);
        }
    }
    int q;
    cin >> q;
    while(q--)
    {
        int a, b;
        cin>>a>>b;
        if(ha[a]==hb[b])
            cout << "Yes\n";
        else
            cout << "No\n";
    }
    return 0;
}
posted @ 2022-05-10 15:38  menitrust  阅读(29)  评论(0编辑  收藏  举报