zoukankan      html  css  js  c++  java
  • 【XSY2988】取石子

    题目来源:NOI2018模拟测试赛(二十六)

    题解:

    设a<b;

    可以先考虑a=1的特殊情况,注意到后手的最优策略是跟着另外一个人取,取到最后剩余不到$a+b$时再看奇偶性;

    那么很容易想到把所有石子按$mod(a+b)$的余数分类:

    1.余数<a:剩下的部分没用;

    2.a≤余数<b:只要有则a必胜;

    3.b≤余数<2a:要考虑奇偶性;

    4.余数≥2a:只要有两个或以上则a必胜,有一个时情况3的为偶数则先手必胜,为奇数则a必胜,没有时情况3为偶数则后手必胜,否则先手必胜;

    随便手推一下就行了。

    ps:场上会a=b和a=1的都写了正解,就我一个zz不会还写挂了部分分……

     1 #include<algorithm>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<queue>
     7 #define inf 2147483647
     8 #define eps 1e-9
     9 #define mod 1000000007
    10 using namespace std;
    11 typedef long long ll;
    12 typedef double db;
    13 int n,a,b,s1,s2,s3,s4,t1,t2,t3,t4,tot=0,x[100001],s[100001];
    14 bool sw=false;
    15 int fastpow(int x,int y){
    16     int ret=1;
    17     for(;y;y>>=1,x=(ll)x*x%mod){
    18         if(y&1)ret=(ll)ret*x%mod;
    19     }
    20     return ret;
    21 }
    22 int main(){
    23     scanf("%d%d%d",&n,&a,&b);
    24     if(a>b){
    25         sw=true;
    26         swap(a,b);
    27     }
    28     for(int i=1;i<=n;i++){
    29         scanf("%d",&x[i]);
    30         x[i]%=(a+b);
    31         if(x[i]<a)s1++;
    32         else if(x[i]<b)s2++;
    33         else if(x[i]<a*2)s3++;
    34         else s4++;
    35     }
    36     if(s3){
    37         t3=t4=fastpow(2,s1+s3-1);
    38     }else t4=fastpow(2,s1);
    39     t3=(t3+(ll)t4*s4%mod)%mod;
    40     t1=((fastpow(2,n)-t3-t4)%mod+mod)%mod;
    41     if(sw)swap(t1,t2);
    42     printf("%d %d %d %d",t1,t2,t3,t4);
    43     return 0;
    44 }
  • 相关阅读:
    【杭电】[2071]无限的路
    【杭电】[1161]Eddy's mistakes
    【杭电】[1859]最小长方形
    【杭电】[2083]简易版之最短距离
    【CodeForces】[614A]Link/Cut Tree
    【杭电】[2076]夹角有多大
    【杭电】[2055]An easy problem
    【杭电】[2036]改革春风吹满地
    【杭电 】[2040]亲和数
    【杭电】[2044]一只小蜜蜂...
  • 原文地址:https://www.cnblogs.com/dcdcbigbig/p/10062865.html
Copyright © 2011-2022 走看看