• 【Codeforces】Educational Codeforces Round 156 [Rated for Div. 2]


    hh本蒟蒻第一次记录cf。

    复盘

    ab题目比较清晰,只开了这两题,后面看了下cd,即使开了翻译也看不懂题目是什么意思,最后放弃睡觉了。。

    a是一道思维题,翻了下别人写的发现大家写的各不相同hh

    b是一道数学题,过程有点繁琐,需要细心。

    Problem - A - Codeforces

    数学巧思

    题意:

    仍然是t组测试哈,给定一个数n,问是否有a+b+c=n,a%3,b%3,c%3不为0,如果存在输出yes并输出这三个数,否则输出no。

    设a=3k1+d1,b=3k2+d2,c=3k3+d3

    显然,d1,d2,d3只能是1或2

    那么我们就只需要对余数进行讨论就行了,

    比如给定1和2,这两个数当然是满足条件的,只需要(n-3)%3不为0就好了,也就是(n-3)=3*k+1或2(k>=1)

    这一个条件不足以涵盖所有情况,也就是只要还需要n-(3*k+1),n-(3*k+2),即覆盖余数为0,1,2这三种情况

    1. #include
    2. signed main()
    3. {
    4. int t;
    5. std::cin>>t;
    6. while(t--)
    7. {
    8. int x;
    9. std::cin>>x;
    10. if((x-3)%3&&(x-3)!=1&&(x-3)!=2&&(x-3)>0)
    11. {
    12. std::cout<<"YES"<<'\n'<<"1 2 "<-3<<'\n';
    13. continue;
    14. }
    15. if((x-5)%3&&(x-5)!=1&&(x-5)!=4&&(x-5)>0)
    16. {
    17. std::cout<<"YES"<<'\n'<<"1 4 "<-5<<'\n';
    18. continue;
    19. }
    20. if((x-7)%3&&(x-7)!=2&&(x-7)!=5&&(x-7)>0)
    21. {
    22. std::cout<<"YES"<<'\n'<<"2 5 "<-7<<'\n';
    23. continue;
    24. }
    25. std::cout<<"NO"<<'\n';
    26. }
    27. return 0;
    28. }

    但其实经过分析可以发现,只需要上面两个if语句就够了,n-3和n-5已经覆盖了所有情况。

     常规循环

    因为思路比较简单我就直接复制的别人的代码,枚举前两个数,范围是1-13,然后对n-i-j进行判断就行。

    1. #define ll long long
    2. #include
    3. using namespace std;
    4. void solve(){
    5. ll n;cin>>n;
    6. for(ll i=1;i<13;i++){
    7. for(ll j=1;j<13;j++){
    8. ll z=n-i-j;
    9. if(z>0 && i!=j && i!=z && j!=z && i%3!=0 && j%3!=0 && z%3!=0){
    10. cout<<"Yes"<<"\n";
    11. cout<" "<" "<"\n";
    12. return;
    13. }
    14. }
    15. }
    16. cout<<"No"<<"\n";
    17. }
    18. int main(){
    19. ll n;cin>>n;
    20. while(n--)solve();
    21. }

    Problem - B - Codeforces

    题目仍然是t个测试点

    题目给出三个点p,a,b,要求以a和b分别为圆心,以w为半径做两个圆

    要求o到p在圆上有路

    思路分析:

    分成两种情况进行讨论:

    1.o,p在同一圆上

    这种情况一定满足o到p在圆上有路,只要讨论哪个点作为圆心就好了。

    要求两点在同一圆上,也就是要取圆心到o,p最大的那个距离作为半径

    s1=min(max(点o到a的距离,p到a的距离),max(点o到b的距离,p到b的距离))

    2.o,p不在同一圆上

    这种情况下想要满足题意还需要满足条件:两圆相切

    s2=(max(点a到点b的距离/4,min(max(点o到a的距离,p到b的距离),max(点o到b的距离,p到a的距离)))

    1. #include
    2. using namespace std;
    3. int dis(int x1,int y1,int x2,int y2)
    4. {
    5. return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
    6. }
    7. signed main()
    8. {
    9. int t;
    10. std::cin>>t;
    11. while(t--)
    12. {
    13. int p1,p2;
    14. int x1,y1;
    15. int x2,y2;
    16. std::cin>>p1>>p2>>x1>>y1>>x2>>y2;
    17. //只要源点和p都在圆上
    18. //
    19. double s1=min(max(dis(p1,p2,x1,y1),dis(0,0,x1,y1)),
    20. max(dis(p1,p2,x2,y2),dis(0,0,x2,y2)));
    21. double hh=(double)dis(x1,y1,x2,y2)/4;
    22. double s2=max(hh,
    23. (double)min(max(dis(p1,p2,x1,y1),dis(0,0,x2,y2) ),
    24. max(dis(p1,p2,x2,y2),dis(0,0,x1,y1))
    25. )
    26. );
    27. double d=min(s1,s2);
    28. d=sqrt(d);
    29. printf("%.10f\n",d);
    30. }
    31. return 0;
    32. }

    Problem - C - Codeforces

    题目大意:

    可喜可贺终于看懂了题目。

     如果要一直变换s并且每一轮都拼接字符串将会非常麻烦,因此我们选择预处理数据n,对比字符串长度求出将要删cnt个字母才能得出答案。

    因此,我们遍历字符串,如果当前字符比栈顶的字符小就出栈,cnt--,如此反复直到cnt为0。

    这时cnt为0,我们按顺序依次把s里剩余的字符压入栈内,下标为n-1的字符就是答案。

    1. #include
    2. typedef long long LL;
    3. void solve()
    4. {
    5. LL n;
    6. std::string s;
    7. std::cin>>s>>n;
    8. int len=s.length();
    9. int cnt;//要删几个
    10. while(n>len)
    11. {
    12. n-=len;
    13. len--;
    14. cnt++;
    15. }//要输出第n个
    16. std::vector<char> st;
    17. for(int i=0;ilength();i++)
    18. {
    19. while(!st.empty()&&cnt&&s[i]back())
    20. {
    21. st.pop_back();
    22. cnt--;
    23. }
    24. st.push_back(s[i]);
    25. }
    26. std::cout<-1];
    27. }
    28. signed main()
    29. {
    30. int t;
    31. std::cin>>t;
    32. while(t--)
    33. {
    34. solve();
    35. }
    36. return 0;
    37. }

    Problem - D - Codeforces

    我的绝望震耳欲聋。。


    自己尝试了800次,怎么都觉得逻辑是对的但却超时,知道了做大数除法要用逆元 ,这时才真正理解了逆元的作用。

    逆元的作用 一句话就是,将除法改为乘法; 例如 求 (A / B) %p ;在B的值非常大的情况下,B作为除数,极有可能会爆精度;除数不能太大;所以我们可以把他转化为乘法来解决; (a/b)mod m = (a/b)*1mod m = (a/b)bc mod

    但本蒟蒻的代码不知道为何最后还是会爆,所以借鉴(照抄)了别人。D. Monocarp and the Set_阿根廷必胜的博客-CSDN博客

    题目大意:

    给定m,n,m代表字符串长度为m-1,有n条操作

     首先输出有几种可能的排序

    然后对每次操作,输入x和字符c,把x位置上的字符替换为c,然后输出此时字符串可能的排序数。

    思路:

    我们将字符串倒着看,如果当前符号为>或<,则此字符只有一种可能。如果当前字符为?,就有i-2种可能,我们把它累乘就行了。

    需要注意的是第一个字符串如果为?,ans*0=0,因为我们后续要替换,0除以任何数都为0 ,直接这样会造成不少的麻烦。

    但是注意,ans=0只会在a[0]=?的情况下发生,因此我们用ans记录从1-m-2的情况数,对0位置进行单独讨论。

    1. #include
    2. #define int long long
    3. const int mod = 998244353;
    4. int qpow(int a, int b)//求逆元
    5. {
    6. int res = 1;
    7. while (b)
    8. {
    9. if (b & 1) res = res * a % mod;
    10. b >>= 1;
    11. a = a * a % mod;
    12. }
    13. return res;
    14. }
    15. signed main()
    16. {
    17. std::ios_base::sync_with_stdio(0); std::cin.tie(0), std::cout.tie(0);
    18. int n,q;
    19. std::string s;
    20. std::cin>>n>>q>>s;
    21. int ans = 1;
    22. for (int i=1;i-1; i++)
    23. {
    24. if (s[i]=='?')
    25. {
    26. ans=ans*i%mod;
    27. }
    28. }
    29. std::cout << (s[0] == '?' ? 0 : ans) << '\n';
    30. while (q--)
    31. {
    32. int i;
    33. char c;
    34. std::cin >> i >> c;
    35. i--;
    36. if (i != 0 && s[i] == '?')
    37. {
    38. ans = ans * qpow(i, mod - 2) % mod;
    39. }
    40. s[i] = c;
    41. if (i != 0 && s[i] == '?')
    42. {
    43. ans = ans * i % mod;
    44. }
    45. std::cout << (s[0] == '?' ? 0 : ans) << '\n';
    46. }
    47. return 0;
    48. }

     复习逆元

    875. 快速幂 - AcWing题库

    快速求出pow(a,k) mod p     时间复杂度O(log,k)

     

    1. #include
    2. typedef long long LL ;
    3. LL qmi(int a,int k,int p)
    4. {
    5. LL res=1;
    6. while(k)
    7. {
    8. if(k&1) res=(LL)res*a%p;
    9. k>>=1;
    10. a=(LL)a*a%p;
    11. }
    12. return res;
    13. }
    14. signed main()
    15. {
    16. std::ios::sync_with_stdio(false);
    17. std::cin.tie(0),std::cout.tie(0);
    18. int n;
    19. std::cin>>n;
    20. while(n--)
    21. {
    22. int a,k,p;
    23. std::cin>>a>>k>>p;
    24. std::cout<<qmi(a,k,p)<<'\n';
    25. }
    26. return 0;
    27. }

    876. 快速幂求逆元 - AcWing题库

    1. #include
    2. typedef long long LL;
    3. LL qmi(int a,int k,int p)
    4. {
    5. LL res=1;
    6. while(k)
    7. {
    8. if(k&1) res=(LL)res*a%p;
    9. k>>=1;
    10. a=(LL)a*a%p;
    11. }
    12. return res;
    13. }
    14. signed main()
    15. {
    16. int n;
    17. std::cin>>n;
    18. while(n--)
    19. {
    20. int a,p;
    21. std::cin>>a>>p;
    22. if(a%p==0) puts("impossible"); //a,p要求互质
    23. else std::cout<<qmi(a,p-2,p)<<'\n';
    24. }
    25. return 0;
    26. }

  • 相关阅读:
    电脑重装系统后台式电脑网卡坏了怎么修复
    微信小程序--》小程序—自定义组件使用
    Qt实战案例(59)——利用QTimer类实现定时器功能
    10.30-11.3|浙大报考点硕士研究生2023年网上确认系统操作流程
    EventSystem 事件系统
    关于对接芝麻 GO 的几点问题
    Redis 集群 & Redis 事务 & Redis 流水线 & Redis 发布订阅 & Redis Lua脚本操作
    【Redis面试】基础题总结(中)
    emqx安装教程
    闯关无边界时代,荣耀与华为全场景OS相见
  • 原文地址:https://blog.csdn.net/m0_74183164/article/details/133750136