首页 > 其他分享 >Educational Codeforces Round 156 (Rated for Div. 2) ABCD

Educational Codeforces Round 156 (Rated for Div. 2) ABCD

时间:2023-11-21 16:12:59浏览次数:55  
标签:ABCD Educational Rated const int double pos long ans

Educational Codeforces Round 156 (Rated for Div. 2) ABCD

A. Sum of Three

题意:给定正整数 \(n\),判断是否存在正整数 \(a\),\(b\),\(c\) 满足:

  • \(a+b+c=n\)。
  • \(a\),\(b\),\(c\) 均不是 \(3\) 的倍数。

如存在,输出 YES 并构造一组方案,否则输出 NO

思路:

法一:我们分类讨论。

根据余数分为:

  • \(n \% 3=0\)

    最小的合法数是\(12=1+4+7\)

  • \(n \% 3=1\)

    最小的合法数是\(7=1+2+4\)

  • \(n \% 3=2\)

    最小的合法数是\(11=1+2+8\)

那么我们发现,\(n\le 6\)的都是不合法的,其他情况可以拆分成\(1,4,n-5\)或者\(1,2,n-3\)

// 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 t; cin>>t;
    while(t--)
    {
        int n; cin>>n;
        if(n<=6)
        {
            cout<<"NO\n";
            continue;
        }
      
        if(n%3==0)//12 = 1 + 4 + 7
        {
            if(n<12){
                cout<<"NO\n";
                continue;
            }
            else
            {
                cout<<"YES\n";
                cout<<1<<" "<<4<<" "<<n-5<<"\n";
            }
        }
        else if(n%3==1)//7 = 1 + 2 + 4
        {
            if(n<7)
            {
                cout<<"NO\n";
                continue;
            }
            cout<<"YES\n";
            cout<<1<<" "<<2<<" "<<n-3<<"\n";
        }
        else if(n%3==2)//11 = 1 + 2 + 8
        {
            if(n<8)
            {
                cout<<"NO\n";
                continue;
            }
            cout<<"YES\n";
            cout<<1<<" "<<2<<" "<<n-3<<"\n";
        }
    }
    return 0;
}

法二:如果不想分类讨论呢,我们可以手玩几个样例,大胆猜测,前两个数一定能在10以内确定下来,暴力枚举即可。

// 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;

void solve(int n)
{
    for(int x = 1; x <= n; x++)
    {
        for(int y = x + 1;y < n-x-y; y++)
        {
            int z = n-x-y;
            if(x % 3 && y % 3 && z % 3 && z > 0)
            {
                cout<<"YES\n";
                cout<<x<<" "<<y<<" "<<z<<"\n";
                return;
            }
        }
    }
    cout<<"NO\n";

    return;
}

int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int t; cin>>t;
    while(t--)
    {
        int n; cin>>n;
        solve(n);
    }


    return 0;
}

B. Fear of the Dark

题意:起点是\((0,0)\),给你终点\((p_x,p_y)\)和两个光源\((A_x,A_y),(B_x,B_y)\)。人从起点到终点且所走的路线一定要被光源覆盖。问最小的光源半径是多少?

思路:考虑合法情况:

  • 两个点被同一个光源覆盖
  • 两个点分别被不用光源覆盖,且两个圆有交(相切也可以)。

我们考虑二分答案,去check就行了

// 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;
double px,py,ax,ay,bx,by;
const double eps = 1e-9; 

double get(double x1,double y1,double x2,double y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

bool in(double r,double d)
{
    return d<=r;
}

bool check(double r)
{
    double da = get(px,py,ax,ay),db = get(px,py,bx,by);
    double do1 = get(0,0,ax,ay),do2 = get(0,0,bx,by);
    if((in(r,da)&&(in(r,do1)))||(in(r,do2)&&in(r,db)))
    {
        return true;
    }
    else
    {
        double ab = get(ax,ay,bx,by);
        if(((in(r,da)&&in(r,do2))||(in(r,db)&&in(r,do1)))&&ab<=2*r)
        {
            return true;
        }
    }
    return false;
}

int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int t; cin>>t;
    while(t--)
    {
        cin>>px>>py>>ax>>ay>>bx>>by;
        double l = 0, r = 1e4, mid, ans;
        while(fabs(l-r)>=eps){
            mid = (l+r)/2;
            if(check(mid))
                r = mid;
            else
                l = mid;
        }
        ans = mid;
        printf("%.12f\n",ans);
    }


    return 0;
}

C. Decreasing String

题意:有 \(t\) 组测试点,每组测试点给出字符串 \(s_1\) 和 一个整数 \(pos\)。

以下列规则得到字符串 $ S $ :

  • 从 $ s_{i - 1} $ 中删除一个字符,字典序最小的记为 $ s_i $
  • $S = s_1 + s_2 + \dots + s_n $

输出字符串 $ S $ 第 \(pos\) 个位置上的字符(即 $ S_{pos} $)。

思路:这题很神奇,思路很巧妙,本人很菜没想出,看jls的代码学习的。

正解是单调栈。

我们每次得到的字符串长度是上次的长度-1。考虑:我们要求最终串的\(pos\)位,我们真的需要知道最终的串长什么样子吗?

不用的,因为\(S = s_1+s_2+...+s_n\),我们只要确定我们的\(pos\)是子串\(s_x\)种的第几位就行了。那么我们得先确定出\(s_x\)是第几个串,和第\(x\)个串的第几个。

我们\(for(i=0~n-1)\)

第\(i\)次的长度是\(n-i\),一旦不够减了,说明\(pos\)在我们的这个串\(i\)里面了

确定出这两个,我们只要求出第\(i\)个串长什么样就可以轻松求得答案了。

因为是第\(i\)个串,说明我们删了\(i\)个字符,我们要保证字典序最小,说明加入的一定是个尽量单调递减的串。我们考虑用单调栈维护。

// 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 t; cin>>t;
    while(t--)
    {
        string s; cin>>s;
        ll n = s.size();
        ll pos; cin>>pos;
        pos--;
        int x, y;
        for (int i = 0; i < n; i++) {
            int len = n - i;
            if (pos < len) {
                x = i;//编号即删的次数
                y = pos;//位置
                break;
            }
            pos -= len;
        }

        string ans = "";//构造第i个串
        for(auto c : s) {
            while(x > 0 && !ans.empty() && c < ans.back()) {
                ans.pop_back();
                x--;
            }
            ans += c;
        }
        cout<<ans[y];
    }

    return 0;
}

D.Monocarp and the Set

题意:

Monocarp有 \(n\) \((2 \leq n \leq 3 \times 10^5)\)个数字 \(1,2,...n\) 以及一个空集合。他每次以一定顺序将数字加入集合。每个步骤中,他会将一个不在集合中的数加入集合。换言之,最终加入集合的顺序是n的一个排列。

从第二次开始,每次monocarp将元素添加到集合中时,他会写下一个字符

  • 如果Monocarp尝试插入的元素成为集合中的最大元素,Monocarp将写下>

  • 如果Monocarp尝试插入的元素成为集合中的最小元素,Monocarp将写下<

  • 如果不符合以上两种情况,Monocarp将写下?

给你一个长度为 \(n-1\) 的字符串 \(s\) ,代表Monocarp按顺序写下的字符,你需要处理 \(m\) \((1 \leq m \leq 3 \times 10^5)\) 次询问,每个询问格式如下:

  • \(i\) \(c\) - 将 \(s_i\) 替换为字符 \(c\)

对于初始字符串和每次查询,请输出一个整数,代表可以得到字符串 \(s\) 的不同插入顺序的数量。由于答案可能很大,只需给出这个数模 \(998244353\) 的结果。

思路:介个题其实思维难度上不大,但是看着吓人。

我们先预处理出初始答案。我们正向考虑,如果当前是\(?\),那么能插入的位置是除了开头和结尾的任意一个(方案数是元素个数-2)。如果是\(> or <\),那么一定是插入到一头或一尾(方案数是1)。

那么:

  • 是\(?\):\(f[i] = f[i-1]*(i-2)\)
  • 是\(> or <\):\(f[i] = f[i-1]*1\)

对于修改操作:如果更改了,其实就是乘上原方案数的逆元再乘修改后方案数即可。

注意:考虑不合法情况,如果一开始是\(?\)肯定是无解的,特判一下就行了。

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int p = 998244353;
const int N = 3e5 + 10;
int n,m;
string s;
bool fg;
ll ans = 1,inv[N];
void init()
{
    s = "?"+s;
    fg = (s[1]!='?');
    for(int i = 2;i < n; i++)
        ans = (ans*(s[i]=='?'?i-1:1))%p;
    inv[1] = 1;
    for (int i = 2; i <= n; ++ i) {
        inv[i] = 1ll * (p - p / i + p) % p * inv[p % i] % p;
    }
}

int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    cin>>n>>m>>s;
    init();
    cout<<(fg?ans:0)<<"\n";
    for(int i = 1;i <= m; i++)
    {
        int pos; char ty;
        cin>>pos>>ty;
        if(pos==1)
            fg = (ty!='?');
        else{
            ans = (ans*(s[pos]=='?'?inv[pos-1]:1))%p;
            ans = (ans*(ty=='?'?pos-1:1))%p;
        }
        s[pos] = ty;
        cout<<(fg?ans:0)<<"\n";

    }
    return 0;
}

标签:ABCD,Educational,Rated,const,int,double,pos,long,ans
From: https://www.cnblogs.com/nannandbk/p/17846814.html

相关文章

  • 【231119-1】如图,在正方形ABCD中,以AB为腰向正方形内部作等腰三角线ABE,点G在CD上,且CG=3
    【题目】如图,在正方形ABCD中,以AB为腰向正方形内部作等腰三角线ABE,点G在CD上,且CG=3DG,链接BG并延长,与AE交于F,与AD延长线交于H。连接DE交BH于点K,连接CK。若AE^2=BFBH,FG=13/5根号5.求:四边形EFKC的面积?【解答】......
  • Educational Codeforces Round 13 E
    tilian最开始看错了以为是可以任意选择两人or选择一人胜出但题意是可以选择下一个擂主是谁考虑dp的话我们显然需要记录一个state以及当前擂主是谁转移就是dp[state][i]=max(dp[state][i],dp[state(1<<j)][j]*a[i][j]+dp[state(1<<i)]*a[j][i])意义是我们枚举他后一个交......
  • 以下对闭包(closure)理解正确的有 ABCD
    以下对闭包(closure)理解正确的有ABCDA闭包是指有权访问另一个函数作用域中变量的函数;B函数内再嵌套函数,返回到外部形成闭包;C内部函数可以引用外层的参数和变量D参数和变量不会被垃圾回收机制回收闭包的作用​ 1可以读取函数内部的变量​ 2可以把变量始终保存在内......
  • Codeforces Round 903 (Div. 3) ABCDE
    CodeforcesRound903(Div.3)ABCDEA.Don'tTrytoCount题意:复制\(s\)串若干遍,是否能在\(s\)串中找到\(t\)串。思路:直接暴力,注意不要超限,会MLE//AConemoretimes//nndbk#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;constintmod=1e9+......
  • Educational Codeforces Round 157 D
    tilian不太会这种题发现找到一个数就能确定整个序列然后转而发现前缀异或和b1^b2=a1b1^b3=a2...我们发现要是n为偶数时能直接求出b1从而确定整个序列而为奇数时我们无法确定b1我们思考拆位之后如果b1该位为0算出真实的异或后的01个数b1该位为1算出真实的......
  • Educational Codeforces Round 126 (Rated for Div. 2)
    https://codeforces.com/contest/1661/B题数据很小,直接bfs预处理就行C题随便猜了一下,设mx=\(max\{a_i\}\)最后的值应该是mx,mx+1,mx+2,mx+3之类的吧D题刚开始从前面考虑,陷入僵局,一度非常的困,学习凯库勒睡了一会,就突然想到了,前面不行,就从后面考虑,可以发现,从后面考虑的话,就非常......
  • Educational Codeforces Round 157 (Rated for Div. 2)
    A.TreasureChest题目大意:人在0处,宝藏在x,钥匙在y,人最多拿宝箱z秒,问你最快多久开宝箱?思路:如果说钥匙在宝箱的左边,那么人只需要往右走就是最佳答案,如果钥匙在宝箱的右边,那么人只需要拿的宝箱到最佳地点就行#include<bits/stdc++.h>usingnamespacestd;voidsolve(){ intx,y......
  • Educational Codeforces Round 157 (Rated for Div. 2)
    F.FancyArrays第一眼感觉是去容斥掉条件1,因为条件2其实挺紧的。不妨用\(f(l,r)\)表示\(a\)值域在\([l,r]\)的方案(满足条件2)。那么答案为\(f(0,+\infty)-f(0,x-1)-f(x+k,+\infty)\),因为如果选了\([0,x-1]\)的数,那么还要更大的话,一定会选到\([x,x+k-1]\),所以你要......
  • 关于topology generated by functions的一些思考
      平时所学的拓扑都是直接给出开集族或者是basisorsubbasis,然后由basisorsubbasis生成拓扑。  前些天看Kechris时,遇到了weaktopology。泛函分析时学过weakconvergence,但没有接触过weaktopology。  它给出的定义是generatedbyfunctions………看到的时候就很纳闷到......
  • Ozon Tech Challenge 2020 (Div.1 + Div.2, Rated, T-shirts + prizes!) B. Kuroni an
    Problem-1305B-Codeforces 啦啦啦,这题题目有点长,概括一下就是,希望将所有()匹配的括号去掉问你需要操作多少次 双指针,一个i一个j,从前往后记录匹配的括号如果发现:1.括号匹配2.i<jok,就放入ans (⊙o⊙)…,最后记得sort一遍ans,第一遍因为这个wa了一发 #include......