• Educational Codeforces Round 136 (Rated for Div. 2)(A~D)


    A. Immobile Knight

    给出一个n*m的棋盘,如果存在一个点使得马可以向任何方向走,输出满足条件的任意一点;否则输出棋盘上任意一点。

    思路:必须满足长大于3,宽大于2才存在满足条件的点,该种条件下输出(m+1)/2,(n+1)/2,否则任意输出一点。

    AC Code:

    1. #include
    2. typedef long long ll;
    3. const int N=105;
    4. int t;
    5. int main(){
    6. std::ios::sync_with_stdio(false);
    7. std::cin.tie(0);
    8. std::cout.tie(0);
    9. std::cin>>t;
    10. while(t--){
    11. int n,m;
    12. std::cin>>n>>m;
    13. int a=std::max(n,m);
    14. int b=std::min(n,m);
    15. if(a>3&&b>2) std::cout<<1<<' '<<1<<'\n';
    16. else std::cout<<(n+1)/2<<' '<<(m+1)/2<<'\n';
    17. }
    18. return 0;
    19. }

    B. Array Recovery

    给出一个数组a,构造一个数组d,满足d[1]=a[1],d[i]=abs(a[i]-a[i-1]),如果这个数组d是唯一的,构造出这个数组,否则输出-1。

    思路:明显考差前缀和。对于a求前缀和数组,对于前缀和数组中的每个元素dif[i],如果它大于a[i+1],那说明下一个数可以是dif[i]+a[i+1],也可以是dif[i]-a[i+1],即不唯一,则输出-1。

    AC Code:

    1. #include
    2. typedef long long ll;
    3. const int N=105;
    4. int t,n;
    5. int a[N],dif[N];
    6. int main(){
    7. std::ios::sync_with_stdio(false);
    8. std::cin.tie(0);
    9. std::cout.tie(0);
    10. std::cin>>t;
    11. while(t--){
    12. std::cin>>n;
    13. for(int i=1;i<=n;i++){
    14. std::cin>>a[i];
    15. dif[i]=dif[i-1]+a[i];
    16. }
    17. bool flag=true;
    18. for(int i=1;i
    19. if(dif[i]>=a[i+1]&&a[i+1]){
    20. flag=false;
    21. break;
    22. }
    23. }
    24. if(!flag){
    25. std::cout<<-1<<'\n';
    26. continue;
    27. }
    28. for(int i=1;i<=n;i++){
    29. std::cout<" \n"[i==n];
    30. }
    31. }
    32. return 0;
    33. }

    C. Card Game

    给出偶数n张牌,每张牌上写着1~n中一个数字且不重复,将这些牌分给A和B两人,每一轮先手出牌,下一个人出牌的数字要大于前一个,否则输,每一轮互换先手,问分牌的方案数,使得:A赢,B赢,平局。(平局是指按照游戏规则出牌,最后两人正好出完所有手中牌)

    思路:首先平局为1,其他情况必存在谁赢谁输的情况,所以我们可以先计算先手必胜,用全部的情况减去先手必胜和平局的这一场。考虑先手必胜时,这个题可以分成两个一组和四个一组的情况,这里我采用的是四个一组的情况。先考虑有八张牌的时候,对于5 6 7 8四张牌的分配来说,如果最大牌在A手中,则先手必胜,这样的话其他的牌可以随机分开,用组合数计算很容易;如果567在A手中,则只需要再在1~4选择一张牌;如果在5~8四张牌中打成平局,即A拿到67两张牌,那该种情况下先手必胜的方案数等于在四张牌局面下的方案数,即1~4四张牌时。所以我们只需要初始化在2张牌和4张牌时的方案数,递推得到答案。

    AC Code:

    1. #include
    2. #define int long long
    3. typedef long long ll;
    4. const int mod=998244353;
    5. const int N=105;
    6. int t,n;
    7. int fact[N],infact[N],f[N];
    8. int pmod(int a,int b){
    9. int res=1;
    10. while(b){
    11. if(b&1) res=res*a%mod;
    12. b>>=1;
    13. a=a*a%mod;
    14. }
    15. return res;
    16. }
    17. void init(){
    18. fact[0]=infact[0]=1;
    19. for(int i=1;i<=N-3;i++){
    20. fact[i]=fact[i-1]*i%mod;
    21. infact[i]=infact[i-1]*pmod(i,mod-2)%mod;
    22. }
    23. }
    24. int C(int n,int x){
    25. return fact[n]*infact[n-x]%mod*infact[x]%mod;
    26. }
    27. signed main(){
    28. std::ios::sync_with_stdio(false);
    29. std::cin.tie(0);
    30. std::cout.tie(0);
    31. init();
    32. f[2]=1,f[4]=3;
    33. for(int i=6;i<=60;i+=2){
    34. f[i]=(C(i-1,i/2)+C(i-4,i/2-3)+f[i-4])%mod;
    35. }
    36. std::cin>>t;
    37. while(t--){
    38. std::cin>>n;
    39. int sum=C(n,n/2);
    40. int a=f[n];
    41. int b=((sum-a-1)%mod+mod)%mod;
    42. int c=1;
    43. std::cout<' '<' '<'\n';
    44. }
    45. return 0;
    46. }

    os:一到组合数学就爆炸了,更何况这个还有博弈呜呜呜

    D. Reset K Edges

    给出一棵树,以1为根节点,可以进行k次操作,每次可以删除一条边,将子节点连到根节点上,问经过k次操作,得到最小的树高是多少。

    思路:显然二分(bushi,对于每次操作,一定是删除最深的点最优,所以二分的是最小的树深,可以在每次check时对于mid深度以下的叶节点都删掉。具体见代码。

    AC Code:

    1. #include
    2. typedef long long ll;
    3. const int N=2e5+5;
    4. int t,n,k,idx,cnt;
    5. int e[N<<1],next[N<<1],head[N<<1],fa[N];
    6. void add_edge(int u,int v){
    7. e[idx]=v;
    8. next[idx]=head[u];
    9. head[u]=idx++;
    10. }
    11. int DFS(int u,int father,int mid){
    12. int max=0;
    13. for(int i=head[u];~i;i=next[i]){
    14. int j=e[i];
    15. if(j==father) continue;
    16. max=std::max(max,DFS(j,u,mid));
    17. }
    18. max++;
    19. if(father==1||u==1) return 0;
    20. if(max>=mid){
    21. cnt++;
    22. return 0;
    23. }
    24. else return max;
    25. }
    26. bool check(int mid){
    27. cnt=0;
    28. DFS(1,0,mid);
    29. return cnt<=k;
    30. }
    31. int main(){
    32. std::ios::sync_with_stdio(false);
    33. std::cin.tie(0);
    34. std::cout.tie(0);
    35. std::cin>>t;
    36. while(t--){
    37. std::cin>>n>>k;
    38. idx=0;
    39. // memset(head,-1,sizeof(head));
    40. for(int i=1;i<=n;i++){
    41. head[i]=-1;
    42. }
    43. for(int i=2;i<=n;i++){
    44. int p;
    45. std::cin>>p;
    46. fa[i]=p;
    47. add_edge(i,p),add_edge(p,i);
    48. }
    49. int l=1,r=n;
    50. while(l
    51. int mid=l+r>>1;
    52. if(check(mid)) r=mid;
    53. else l=mid+1;
    54. }
    55. std::cout<'\n';
    56. }
    57. return 0;
    58. }

     

  • 相关阅读:
    20 _ 散列表(下):为什么散列表和链表经常会一起使用?
    人工智能CV应用现状与发展 - 讲座记录
    致敬记者节,合合信息扫描全能王助力新闻工作者构建“随身资料库”
    Java编程常见问题汇总六
    Android 单ABI架构适配指南:保姆级教学 INSTALL_FAILED_NO_MATCHING_ABIS
    [msyql]实战:关于回表的一次查询优化实战
    泰山OFFICE技术讲座:着重号引起的行高变化
    推广明星产品回报最大,推广新产品风险最大,为何还要推广新品?
    Latex语法学习10:盒子的使用(fbox, tcolorbox, boitee),支持设置颜色和换页
    Torch生成类激活图CAM
  • 原文地址:https://blog.csdn.net/m0_62289613/article/details/127134162