2023 CCPC 哈尔滨 BLM

发布时间 2023-11-23 23:55:10作者: nannan4128

[2023 CCPC 哈尔滨](The 2nd Universal Cup. Stage 10: Harbin - Dashboard - Contest - Universal Cup Judging System (ucup.ac)) BLM

B.Memory

思路:由递推式:\(Mood(i) = \sum_{j =1}^{i}2^{j-i}\times a_j\)可知,\(f[i] = f[i-1]/2+a[i]\)

显然直接\(/2\)会有精度问题啦,怎么办嘞。考虑把数分为整数部分和小数部分,分类讨论:

  • \(Mood(i)<0\)
    1. 整数部分\(<0\)
    2. 整数部分\(=0\)且小数部分\(<0\)
  • \(Mood(i)=0\):整数部分\(=0\)并且没有小数部分
  • \(Mood(i)>0\)
    1. 整数部分\(>0\)
    2. 整数部分\(=0\)且小数部分\(>0\)
// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;

int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int n; cin>>n;
    ll x = 0,dec = 0;
    string ans = "";
    for(int i = 1;i <= n; i++)
    {
        ll y; cin>>y;
        x += y;
        if(x)
            ans += (x>0?"+":"-");
        else{
            if(dec)
                ans += (dec>0?"+":"-");
            else ans += "0";
        }

        if(x%2)
            dec = (x>0?1:-1);
        x/=2;
    }

    cout<<ans<<"\n";

    return 0;
}

以上是正解,但是发现\(python\)大数写居然可以暴力\(AC\)?神奇

L.Palm Island

题意:把数组\(a\)变成\(b\)

只能通过以下两种操作:

  • 把第一个移到最后
  • 把第二个移到最后

且操作次数\(\le n^2\)

思路:考虑用\(map\)\(a\)\(b\)中的位置做一个映射,这样相当于是现在只需要把映射之后的数组\(c\)排序即可。

我们思考这两个操作到底是什么含义。

这样子移动,变成有序,让我们联想到冒泡排序:

void bubble_sort(int arr[], int len)  
{  
    int i, j;  
    for (i = 0; i < len; i++)  
        for (j = 1; j < len - i; j++)  
            if (arr[j - 1] > arr[j])  
                swap(arr[j - 1], arr[j]);  
}

一轮排好一个,又回到开头去比较。类比到我们这题的两个操作:

我们考虑一个指针\(cur\)一开始指在\(0\)位置(初始位置)

  • 把第一个移到最后:等价于指针后移
  • 把第二个移到最后:等价于交换\(cur\)\(cur+1\)位置的值之后指针后移

所以我们只需要按照冒泡排序的思想去写就行了。

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
int a[N],b[N],c[N];
int mp[N];
int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int t; cin>>t;
    while(t--)
    {
        int n; cin>>n;
        int cur = 0;
        for(int i = 0;i < n; i++)
            cin>>a[i];
        for(int i = 0;i < n; i++)
            cin>>b[i],mp[b[i]] = i;
        for(int i = 0;i < n; i++)
            c[i] = mp[a[i]];

        string ans = "";
        while(1)
        {
            if(cur == 0){
                int ok = 1;
                for(int i = 0;i < n-1; i++)
                    ok &= c[i]<c[i+1];
                if(ok)
                    break;
            }
            if(cur < n-1 && c[cur] > c[cur + 1]){
                swap(c[cur],c[cur+1]);
                cur++;
                ans += "2";
            }else{
                ans += "1";
                cur++;
            }
            cur %= n;
        }
        cout<<ans<<"\n";
    }
    return 0;
}

M.Painter

题意:三种操作:画圆、画长方形、打印。输出打印的图

思路:这题我们发现,虽然坐标的数据范围很大但是打印出来的部分面积很小只有\(1e4\),那直接离线然后暴力做就行了。

本题难点在于坐标的映射,两个坐标系的转换要小心。(debug了好久QAQ)

坐标映射应该是下面酱紫滴:

image

也就是原坐标的\((-5,5)\)对应我们的\((1,1)\)以此类推。

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
vector<array<ll,6>>event;
int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int n; cin>>n;
    for(int i = 1;i <= n; i++)
    {
        string ty; cin>>ty;
        if(ty == "Circle"){
            ll x,y,r;
            char col;  cin>>x>>y>>r>>col;
            event.push_back({1,x,y,r,(ll)col,0});
        }else if(ty == "Rectangle"){
            ll x1,y1,x2,y2;
            char col;  cin>>x1>>y1>>x2>>y2>>col;
            event.push_back({2,x1,y1,x2,y2,(ll)col});
        }else if(ty == "Render"){
            ll x1,y1,x2,y2; cin>>x1>>y1>>x2>>y2;
            event.push_back({3,x1,y1,x2,y2,0});
        }
    }


    for(int i = 0;i < n; i++)
    {
        int op = event[i][0];
        // cout<<"op = "<<op<<'\n';
        if(op == 3){
            ll x1 = event[i][1],y1 = event[i][2];
            ll x2 = event[i][3],y2 = event[i][4];

            ll h = y2-y1+1, w = x2-x1+1;
            char a[h+10][w+10];
            memset(a,0,sizeof(a));
            for(int j = 0;j <= h; j++)
                for(int k = 0;k <= w; k++)
                    a[j][k] = '.';
            ll idx[h+10],idy[w+10];
            memset(idx,0,sizeof(idx));
            memset(idy,0,sizeof(idy));
            ll t = y2;
            for(int j = 1;j <= h; j++)
                idx[j] = t,t--;
            t = x1;
            for(int j = 1;j <= w; j++)
                idy[j] = t,t++;

            // cout<<"debug:__________________________\n";
            //  for(int j = 1;j <= h; j++)
            //     cout<<idx[j]<<" ";
            // cout<<"\n";
    
            // for(int j = 1;j <= w; j++)
            //      cout<<idy[j]<<" ";
            // cout<<"\n";

            // for(int i = 1;i <= h; i++)
            // {
            //     for(int j = 1;j <= w; j++)
            //     {
            //         cout<<"("<<idy[j]<<","<<idx[i]<<")";
            //     }
            //     cout<<"\n";
            // }

            for(int j = 0;j < i; j++)
            {
                op = event[j][0];
                if(op==1){
                    ll u = event[j][1],v = event[j][2],r = event[j][3],col = event[j][4];
                    //cout<<"u = "<<u<<" v = "<<v<<"\n";
                    for(int k = 1;k <= h; k++)
                        for(int l = 1;l <= w; l++){

                        //cout<<"idx[k] = "<<idx[k]<<" idy[l] = "<<idy[l]<<"\n";
                        if((u-idy[l])*(u-idy[l])+(v-idx[k])*(v-idx[k])<=r*r)
                            a[k][l] = char(col);
                        }
                            
                        
                }else if(op==2){
                    ll x1 = event[j][1],y1 = event[j][2];
                    ll x2 = event[j][3],y2 = event[j][4];
                    ll col = event[j][5];

                     for(int k = 1;k <= h; k++)
                        for(int l = 1;l <= w; l++)if(x1<=idy[l]&&idy[l]<=x2&&y1<=idx[k]&&idx[k]<=y2){
                            a[k][l] = char(col);
                        }
                }
            }

            for(int j = 1;j <= h; j++)
            {
                for(int k = 1;k <= w; k++)
                    cout<<a[j][k];
                cout<<"\n";
            }

        }
    }

    return 0;
}