codeforces round 862

A.

和洛谷上的删数思路一致,后者是找峰顶,这个是找谷底

从前到后枚举每一位与要添加的数比大小,如果要添加的数 <= 该位的数,就继续枚举,否则就将这个数添加在其前面

B.

需要移动的步数 = 两个点所在的层数之差的绝对值,只要计算出所在层数就可以

一开始没想明白怎么算这个层数,先把每个点都变换到了整个图的左下角的1/4块

if x > n / 2, x = n + 1 - x;  if y > n / 2, y = n + 1 - y;

两个点 P (x1,y1) Q(x2,y2);

ans = abs ( min (x1,y1) - min(x2, y2) ) 

C.

b[i] <= a[i-1] && b[i] <= a[i]

所以答案就是b[i] = min (a[i[, a[i-1]) ,初始化 a[0] = a[n+1] = 1e9 + 1;

D.

 ***,再一次读错题,以为是分割成长方形,结果是正方形,没想明白

如果是正方形其实就很好想了,一个为 n 的长方形最终一定会被分割成分别 f [0],f [1],f [2]……f [n] 大小的正方形

对于点 (x,y),如果 y > f[n] 那么f[n] 大小的正方形就在左侧,右边部分横过来就是 n - 1 的长方形

反之,如果 y <= f [n-1] ,则将 f[n] 大小的正方形放在右侧,左边部分横过来就是 n - 1 的长方形

如果都不在,那么一定是无法分割的,返回False , 递归出口是 n == 0,能递归到此说明可以,返回 True

#include<bits/stdc++.h>

typedef long long LL;
using namespace std; 

int T;
int n;
LL x,y;
LL f[50];

int dfs(int n,LL x,LL y)
{
    if(n == 0) return 1;
    if(y > f[n]) return dfs(n-1,y-f[n],x);
    else if(y <= f[n-1]) return dfs(n-1,f[n-1]-y+1,x); 
    else return 0;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    f[0] = f[1] = 1;
    for(int i = 2;i <= 45;i++) f[i] = f[i-1] + f[i-2];
    cin>>T;
    while(T--)
    {
        cin>>n>>x>>y;
        if(dfs(n,x,y)) cout<<"Yes\n";
        else cout<<"No\n";
    }
    return 0;
}
View Code

 

E.

从高到低枚举每一位

首先考虑如何求得一个数字在该数组的位置

对于一个数字 abcde

从 0 开始计数,其所处位置为 a * 9^4 + b * 9^3 + c * 9^2 + d * 9^1 + e * 9^0 + 1

其中,如果 a >= 4,则在计算位置时 a -= 1,因为不能包含4这个数,bcde以此类推

对上面式子进一步解释,也就是其位置 = 以 0 ~ a-1 开头的不含4的五位数个数 + 以 0 ~ b-1 开头的不含4的四位数个数+ 三位 + 两位 + 一位 + 1

如果是从 1 开始计数,那么就 - 1 得到 a * 9^4 + b * 9^3 + c * 9^2 + d * 9^1 + e * 9^0

只需要将这个过程倒推就可以得到对应位置的数字

每次另 k 对 9 取余,所得即为该位的数字,注意,如果余数 >= 4 ,需要 +1 

#include<bits/stdc++.h>

typedef long long LL;
using namespace std;

int T;
LL k;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    cin>>T;
    while(T--)
    {
        string a = "";
        cin>>k;
        while(k)
        {
            int t = k % 9;
            if(t >= 4) t++;
            a += '0' + t;
            k /= 9;
        }
        int siz = a.size();
        reverse(a.begin(),a.end());
        cout<<a<<'\n';
    }
    return 0;
}
View Code

另一个正向推的解法

从最高位向最低位依次枚举1 - 9, 不包含4, 一定是从小到大枚举

变量poi 记录第 i 位数字,初始 poi = 0

那么对于第 i 位数字 j,以它为开头的不含 4 的数字个数为 9^(i-1),如果 k > 9^(i-1),则  k -= 9^(i-1), poi = j ,

#include<bits/stdc++.h>

typedef long long LL;
using namespace std;

int T;
LL s[20];
LL k;
LL ans;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    s[0] = 1;
    s[1] = 9;
    for(int i = 2;i <= 17;i++) s[i] = 9 * s[i-1];
    
    cin>>T;
    while(T--)
    {
        cin>>k;
        k++;
        ans = 0;
        for(int i = 15;i >= 1;i--)
        {
            int now = 0;
            for(int j = 1;j <= 9;j++)
            {
                if(j == 4) continue;
                if(k > s[i-1])
                {
                    k -= s[i-1];
                    now = j;
                }
            }
            ans = ans * 10 + now;
        }
        cout<<ans<<'\n';
    }
    return 0;
}
View Code

 同时4也可以变成任何0 - 9 的数

posted @ 2023-04-05 12:03  是谁不可理喻  阅读(15)  评论(0)    收藏  举报