• [SinGuLaRiTy] Nescafe 24杯模拟赛


    【SinGularLaRiTy-1044】 Copyright (c) SinGuLaRiTy 2017. All Rights Reserved.

    小水塘(lagoon)

    题目描述

    忘川沧月的小水塘的水面是一片由以下两种图形组成的图案:

    <图lagoon-1>

    这两种图形都由一个边长为2的正方形和两个半径为1的1/4圆组成,圆心在正方形的两个对角顶点上。
    小水塘左上角坐标为(0,0),右下角坐标为(2*n,2*m)。水面上每一个顶点坐标为偶数的2*2正方形,都是上面两个图形中的一种。如果我们往水塘中的某个位置倒一桶污水,那么这桶污水会像画图中的油漆桶一样扩散开来,占据一片连续的区域,但是在线条边界处会停止扩散。注意如果倒在了线条上,扩散面积为0。
    如下图所示,就是一个由4行4列上述图形组成的、左上角坐标(0,0)、右下角坐标(8,8)、某些位置倒了污水的水塘(白色部分为线条边界,线条实际宽度认为是0,为了明显、美观,此处加粗显示):

    <图lagoon-2>

    现在给出一个n行m列的由上述两种图形组成的水塘,起初水塘中全部为净水。给定q个往某个坐标上(x,y)倾倒污水的操作,对于每次操作,请求出在(x,y)上倾倒的污水最终会扩散多大的面积。

    输入格式

    第一行两个整数n、m。
    接下来n行每行m个整数,每个整数是0或者1,中间没有空格隔开。0代表此处是<图lagoon-1>中左侧那个2*2的图形,1代表此处是右侧那个图形。例如<图lagoon-2>中的第一行用“0001”表示。
    第n+2行是一个整数q。
    接下来q行每行两个用空格隔开的整数x、y,表示这一次倾倒污水的坐标。

    输出格式

    对于每个询问,输出此次倾倒的污水最终扩散的面积,四舍五入保留4位小数。

    样例数据

    样例输入1 样例输出1
    1 2
    0 1
    4
    0 0
    2 0
    0 1
    0 2
    0.7854
    4.8584
    0.0000
    4.8584
    样例输入2 样例输出2
    3 1
    1
    0
    1
    2
    3 1
    4 2
    7.2876
    1.5708

    <数据范围>

    对于 100% 的数据,1<=n,m,q<=100,0<=x<=2*n,0<=y<=2*m。

    解析

    看到数据范围很小,自然地考虑用搜索。由于只有两种图案,若进行搜索,需要考虑 2*4=8 种可能的情况。需要注意的是,如图所示,污水若覆盖了A,那么污水可能覆盖了B,也可能没有覆盖B——这就意味着要把这两个区域的vis访问情况分开进行记录。(这题的if串也是没的说了)

    Code

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    
    using namespace std;
    
    const double pi=acos(-1.0);
    const double big=4-0.5*pi;
    const double small=0.25*pi;
    
    int map[101][101];
    int col[101][101][3]={0};
    int list[501][501];
    
    double all[10001];
    
    struct P{
        int x,y,k;
    }now;
    queue<P> q;
    
    int n,m,qq;
    
    inline void flod(int x,int y,int k,int cnt)
    {
        now.x=x;
        now.y=y;
        now.k=k;
        q.push(now);
        while(!q.empty())
        {
            now=q.front();
            q.pop();
            if(col[now.x][now.y][now.k])
                continue;
            col[now.x][now.y][now.k]=cnt;
            if(now.k!=1)
                all[cnt]+=small;
            else
                all[cnt]+=big;
            if(map[now.x][now.y]==0)
            {
                if(now.k==0)
                {
                    if(now.x-1)
                    {
                        if(map[now.x-1][now.y]==0)
                            q.push((P){now.x-1,now.y,1});
                        else
                            q.push((P){now.x-1,now.y,2});
                    }
                    if (now.y-1)
                    {
                        if(map[now.x][now.y-1]==0)
                            q.push((P){now.x,now.y-1,1});
                        else
                            q.push((P){now.x,now.y-1,0});
                    }
                }
                if(now.k==1)
                {
                    if(now.x-1)
                    {
                        if(map[now.x-1][now.y]==0)
                            q.push((P){now.x-1,now.y,2});
                        else
                            q.push((P){now.x-1,now.y,1});
                    }
                    if (now.y-1)
                    {
                        if(map[now.x][now.y-1]==0)
                            q.push((P){now.x,now.y-1,2});
                        else
                            q.push((P){now.x,now.y-1,1});
                    }
                    if(now.x+1<=n)
                    {
                        if(map[now.x+1][now.y]==0)
                            q.push((P){now.x+1,now.y,0});
                        else
                            q.push((P){now.x+1,now.y,1});
                    }
                    if (now.y+1<=m)
                    {
                        if(map[now.x][now.y+1]==0)
                            q.push((P){now.x,now.y+1,0});
                        else
                            q.push((P){now.x,now.y+1,1});
                    }
                }
                if(now.k==2)
                {
                    if(now.x+1<=n)
                    {
                        if(map[now.x+1][now.y]==0)
                            q.push((P){now.x+1,now.y,1});
                        else
                            q.push((P){now.x+1,now.y,0});
                    }
                    if(now.y+1<=m)
                    {
                        if(map[now.x][now.y+1]==0)
                            q.push((P){now.x,now.y+1,1});
                        else
                            q.push((P){now.x,now.y+1,2});
                    }
                }
            }
            else
            {
                if(now.k==0)
                {
                    if(now.x-1)
                    {
                        if(map[now.x-1][now.y]==0)
                            q.push((P){now.x-1,now.y,2});
                        else
                            q.push((P){now.x-1,now.y,1});
                    }
                    if(now.y+1<=m)
                    {
                        if(map[now.x][now.y+1]==0)
                            q.push((P){now.x,now.y+1,0});
                        else
                            q.push((P){now.x,now.y+1,1});
                    }
                }
                if(now.k==1)
                {
                    if(now.x-1)
                    {
                        if(map[now.x-1][now.y]==0)
                            q.push((P){now.x-1,now.y,1});
                        else
                            q.push((P){now.x-1,now.y,2});
                    }
                    if(now.y-1)
                    {
                        if(map[now.x][now.y-1]==0)
                            q.push((P){now.x,now.y-1,1});
                        else
                            q.push((P){now.x,now.y-1,0});
                    }
                    if(now.x+1<=n)
                    {
                        if(map[now.x+1][now.y]==0)
                            q.push((P){now.x+1,now.y,1});
                        else
                            q.push((P){now.x+1,now.y,0});
                    }
                    if(now.y+1<=m)
                    {
                        if(map[now.x][now.y+1]==0)
                            q.push((P){now.x,now.y+1,1});
                        else
                            q.push((P){now.x,now.y+1,2});
                    }
                }
                if(now.k==2)
                {
                    if(now.x+1<=n)
                    {
                        if(map[now.x+1][now.y]==0)
                            q.push((P){now.x+1,now.y,0});
                        else
                            q.push((P){now.x+1,now.y,1});
                    }
                    if(now.y-1)
                    {
                        if(map[now.x][now.y-1]==0)
                            q.push((P){now.x,now.y-1,2});
                        else
                            q.push((P){now.x,now.y-1,1});
                    }
                }
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;++i)
            for (int j=1;j<=m;++j)
            {
                char ch;ch=getchar();
                while(ch!='1'&&ch!='0')
                    ch=getchar();
                map[i][j]=ch-'0';
            }
        scanf("%d",&qq);
        int cnt=0;
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
                for(int k=0;k<=2;++k)
                    if(!col[i][j][k])
                        flod(i,j,k,++cnt);
        for(int i=1;i<=n;++i)
            for(int j=1;j<=m;++j)
            {
                int xx=i-1,yy=j-1;
                if (map[i][j]==0)
                {
                    list[xx*2][yy*2]=col[i][j][0];
                    list[xx*2+1][yy*2+1]=col[i][j][1];
                    list[xx*2+2][yy*2]=col[i][j][1];
                    list[xx*2][yy*2+2]=col[i][j][1];
                    list[xx*2+2][yy*2+2]=col[i][j][2];
                }
                if (map[i][j])
                {
                    list[xx*2][yy*2]=col[i][j][1];
                    list[xx*2+1][yy*2+1]=col[i][j][1];
                    list[xx*2+2][yy*2+2]=col[i][j][1];
                    list[xx*2+2][yy*2]=col[i][j][2];
                    list[xx*2][yy*2+2]=col[i][j][0];
                }
            }
        while (qq--)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            if((x%2)!=(y%2))
            {
                printf("0.0000
    ");
                continue;
            }
            printf("%.4f
    ",all[list[x][y]]);
        }
    }

    颂芬梭哈(ptgiving)

    题目描述

    Alice 和 Mukyu 最近偶然得到了一本写有一种叫做梭哈的扑克游戏的规则的说明书(名为《C████████nd》,中间部分被涂掉了),据其所述,梭哈是一种使用黑桃、红心、梅花、方片的 A 到 K 共 52 张牌(没有大小王)来进行的扑克牌游戏。
    不幸的是,规则说明中有关整个游戏的进行方式的部分被撕掉了,Alice 和 Mukyu 从残存的部分只得知了“手牌上限是 5 张”这一消息,所以他们决定每次直接给两人各发 5 张牌,判定谁的手牌比较大,说明书中关于手牌大小判定的信息如下:

    所有五张牌的组合,按以下秩序,由大至小排行分为不同牌型:
    1、同花顺(Straight Flush):同一花色,顺序的牌。 例: Q♦ J♦ 10♦ 9♦ 8♦;
    2、四条(Four of a Kind):有四张同一点数的牌。 例: 10♣ 10♦ 10♥ 10♠ 9♥;
    3、满堂红(Full House):三张同一点数的牌,加一对其他点数的牌。 例: 8♣ 8♦ 8♠ K♥ K♠;
    4、同花(Flush):五张同一花色的牌。 例: A♠ K♠ 10♠ 9♠ 8♠;
    5、顺子(Straight):五张顺连的牌。 例: K♦ Q♥ J♠ 10♦ 9♦;
    6、三条(Three of a kind):有三张同一点数的牌。 例: J♣ J♥ J♠ K♦ 9♠;
    7、两对(Two Pairs):两张相同点数的牌,加另外两张相同点数的牌。 例: A♣ A♦ 8♥ 8♠ Q♠;
    8、一对(One Pair):两张相同点数的牌。 例: 9♥ 9♠ A♣ J♠ 8♥;
    9、无对(Zilch):不能排成以上组合的牌,以点数决定大小。例: A♦ Q♦ J♠ 9♣ 8♣。
    若牌型一样则利用点数和花色决定胜负。(点数优先)
    点数的顺序(从大至小)为:A>K>Q>J>10>9>8>7>6>5>4>3>2。(注:当 5 张手牌是 5
    4 3 2 A 的时候,A 可以看作最小的牌,此时的牌型仍然为顺子,是顺子里面最小的一个)。
    花色的顺序(大至小)为:黑桃(♠)>红心(♥)>梅花(♣)>方块(♦)。
    举例说明:
    1、Q♦ J♦ 10♦ 9♦ 8♦ > 8♣ 8♥ 8♠ K♥ K♠ (前者牌型为同花顺,比后者大);
    2、9♣ 9♦ 9♠ Q♥ Q♠ > 8♣ 8♦ 8♠ K♥ K♠ (两者牌型均为满堂红,比较牌型中三张同一点数的牌 9 比 8 大);
    3、A♣ A♦ 8♥ 8♠ Q♠ > A♠ A♥ 7♥ 7♠ K♠ (两者牌型均为两对,且最大的对子相同,此时比较次大的对子,8 比 7 大);
    4、A♠ Q♠ J♥ 9♥ 8♥ > A♦ Q♦ J♠ 9♣ 8♣ (两者牌型均为无对,所有数码均相同,此时比较最大牌的花色,A♠ > A♦)。
    5、4♠ 4♥ A♦ Q♦ 5♦ > 4♣ 4♦ A♠ Q♠ 5♠ (两者牌型均为一对,所有数码均相同,此时对 4 为牌型里最大的部分,因此比较 4♠ > 4♣)

    尽管 Alice 和 Mukyu 都可以轻易的判断出结果,他们还是想见识一下现代科技的力量。

    输入格式

    第一行包含一个正整数 N,表示有 N 组测试数据。
    每组测试数据包含 10 行,前 5 行每行用两个整数描述一张 Alice 手上的牌,第一个数表示牌的数码(1 表示 A,13 表示 K),第二个数表示牌的花色(1 表示黑桃,2 表示红心, 3 表示梅花,4 表示方块)。
    后 5 行每行用两个整数描述 Mukyu 手上的牌,格式同上。

    输出格式

    对于每组测试数据,在单独的一行内输出 Alice 或 Mukyu,表示谁能赢。

    样例数据

    样例输入 样例输出

    1
    1 3
    5 3
    4 3
    3 3
    2 3
    6 1
    10 4
    7 1
    8 1
    9 2

    Alice

    <样例解释>

    Alice 的手牌构成同花顺,而 Mukyu 的手牌仅构成普通顺子。

    <数据范围>

    对于 10%的数据,保证输入的全部牌型都是无对。
    对于另外 30%的数据,保证输入的全部牌型都是顺子、同花或同花顺。
    对于 100%的数据,保证 N ≤ 100000。
    C++选手如果使用 cin 读入数据很可能因此超时,推荐使用 scanf/printf。

    解析

    模拟:一大堆 if串+函数 考虑每一种牌型比较的情况。

    Code

    #include<iostream> 
    #include<cstdio> 
    #include<cstring> 
    #include<algorithm> 
    
    #define num first 
    #define col second 
    #define mp make_pair 
    
    using namespace std; 
    
    typedef pair<int,int> pii; 
    const int N=5+5; 
    
    int cnt[20]; 
    
    inline void getint(int&num){ 
        char c;num=0; 
        while((c=getchar())<'0'||c>'9'); 
        while(c>='0'&&c<='9'){num=num*10+c-48;c=getchar();} 
    } 
    
    int T;pii Ail[N],Muk[N]; 
    bool cmp(pii a,pii b){ 
        if(a.num==b.num) 
            return a.col>b.col; 
        else return a.num<b.num; 
    } 
    bool isone(pii *arr){//同花顺 
        memset(cnt,0,sizeof cnt); 
        for(int i=1;i<=5;i++){ 
            if(arr[i].col!=arr[1].col) 
                return 0; 
            cnt[arr[i].num]++; 
            if(arr[i].num==1) 
                cnt[14]++; 
        } 
        for(int i=1;i<=10;i++) 
            if(cnt[i]==1&&cnt[i+1]==1&&cnt[i+2]==1&&cnt[i+3]==1&&cnt[i+4]==1) 
                return 1; 
        return 0; 
    } 
    bool istwo(pii *arr){//四条 
        bool f=1; 
        for(int i=2;i<=4;i++) 
            if(arr[i].num!=arr[1].num){ 
                f=0;break ; 
            } 
        if(f) return 1; 
        f=1; 
        for(int i=3;i<=5;i++) 
            if(arr[i].num!=arr[2].num){ 
                f=0;break ; 
            } 
        return f; 
    } 
    bool isthree(pii *arr){//满堂红 
        if(arr[1].num==arr[2].num&&arr[1].num==arr[3].num&&arr[4].num==arr[5].num) 
            return 1; 
        if(arr[1].num==arr[2].num&&arr[3].num==arr[4].num&&arr[3].num==arr[5].num) 
            return 1; 
        return 0; 
    } 
    bool isfour(pii *arr){//同花 
        for(int i=2;i<=5;i++) 
            if(arr[i].col!=arr[1].col) 
                return 0; 
        return 1; 
    } 
    bool isfive(pii *arr){//顺子 
        memset(cnt,0,sizeof cnt); 
        for(int i=1;i<=5;i++){ 
            cnt[arr[i].num]++; 
            if(arr[i].num==1) 
                cnt[14]++; 
        } 
        for(int i=1;i<=10;i++) 
            if(cnt[i]==1&&cnt[i+1]==1&&cnt[i+2]==1&&cnt[i+3]==1&&cnt[i+4]==1) 
                return 1; 
        return 0; 
    } 
    bool issix(pii *arr){//三条 
        if(arr[1].num==arr[2].num&&arr[1].num==arr[3].num) 
            return 1; 
        if(arr[2].num==arr[3].num&&arr[2].num==arr[4].num) 
            return 1; 
        if(arr[3].num==arr[4].num&&arr[3].num==arr[5].num) 
            return 1; 
        return 0; 
    } 
    bool isseven(pii *arr){//两对 
        memset(cnt,0,sizeof cnt); 
        for(int i=1;i<=5;i++) 
            cnt[arr[i].num]++; 
        int tot=0; 
        for(int i=1;i<=13;i++) 
            if(cnt[i]==2) tot++; 
        return tot==2; 
    } 
    bool iseight(pii *arr){//一对 
        for(int i=2;i<=5;i++) 
            if(arr[i].num==arr[i-1].num) 
                return 1; 
        return 0; 
    } 
    int check(pii *arr){ 
        if(isone(arr)) return 1; 
        else if(istwo(arr)) return 2; 
        else if(isthree(arr)) return 3; 
        else if(isfour(arr)) return 4; 
        else if(isfive(arr)) return 5; 
        else if(issix(arr)) return 6; 
        else if(isseven(arr)) return 7; 
        else if(iseight(arr)) return 8; 
        else return 9; 
    } 
    bool cmp1(pii *a,pii *b){//同花顺 
        bool f1=0,f2=0; 
        if(a[1].num==1&&a[5].num==13) f1=1; 
        else if(b[1].num==1&&b[5].num==13) f2=1; 
        if(f1!=f2) return f1; 
        if(f1&&f2) return a[1].col<b[1].col; 
          
        if(a[1].num==b[1].num) 
            return a[1].col<b[1].col; 
        else return a[1].num>b[1].num; 
    } 
    bool cmp2(pii *a,pii *b){//四条 
        int num_a1,num_a2,col_a; 
        if(a[1].num==a[2].num&&a[1].num==a[3].num&&a[1].num==a[4].num){ 
            num_a1=a[1].num,num_a2=a[5].num; 
            col_a=a[5].col; 
        } 
        else{ 
            num_a1=a[2].num,num_a2=a[1].num; 
            col_a=a[1].col; 
        } 
          
        int num_b1,num_b2,col_b; 
        if(b[1].num==b[2].num&&b[1].num==b[3].num&&b[1].num==b[4].num){ 
            num_b1=b[1].num,num_b2=b[5].num; 
            col_b=b[5].col; 
        } 
        else{ 
            num_b1=b[2].num,num_b2=b[1].num; 
            col_b=b[1].col; 
        } 
          
        if(num_a1==1) num_a1=14; 
        if(num_a2==1) num_a2=14; 
        if(num_b1==1) num_b1=14; 
        if(num_b2==1) num_b2=14; 
          
        if(num_a1!=num_b1) 
            return num_a1>num_b1; 
        else{ 
            if(num_a2!=num_b2) 
                return num_a2>num_b2; 
            else return col_a<col_b; 
        } 
    } 
    bool cmp3(pii *a,pii *b){//满堂红 
        for(int i=1;i<=5;i++) 
            if(a[i].num==1) a[i].num=14; 
        for(int i=1;i<=5;i++) 
            if(b[i].num==1) b[i].num=14; 
        sort(a+1,a+6,cmp); 
        sort(b+1,b+6,cmp); 
          
        int sta1,sta2,stb1,stb2; 
        if(a[1].num==a[2].num&&a[1].num==a[3].num)  
            sta1=1,sta2=4; 
        else sta1=3,sta2=1; 
          
        if(b[1].num==b[2].num&&b[1].num==b[3].num)  
            stb1=1,stb2=4; 
        else stb1=3,stb2=1; 
          
        for(int i=sta1+2,j=stb1+2;i>=sta1&&j>=stb1;i--,j--){ 
            if(a[i].num==b[j].num) continue ; 
            else return a[i].num>b[j].num; 
        } 
          
        for(int i=sta2+1,j=stb2+1;i>=sta2&&j>=stb2;i--,j--){ 
            if(a[i].num==1) a[i].num=14; 
            if(b[j].num==1) b[j].num=14; 
            else if(a[i].num==b[j].num) continue ; 
            else return a[i].num>b[j].num; 
        } 
          
        for(int i=sta1+2,j=stb1+2;i>=sta1&&j>=stb1;i--,j--){ 
            if(a[i].col==b[j].col) continue ; 
            else return  a[i].col<b[i].col; 
        } 
          
        for(int i=sta2+1,j=stb2+1;i>=sta2&&j>=stb2;i--,j--){ 
            if(a[i].col==b[j].col) continue ; 
            else return  a[i].col<b[i].col; 
        } 
          
        return 1; 
    } 
    bool cmp4(pii *a,pii *b){//同花 
        for(int i=1;i<=5;i++) 
            if(a[i].num==1) a[i].num=14; 
        for(int i=1;i<=5;i++) 
            if(b[i].num==1) b[i].num=14; 
        sort(a+1,a+6,cmp); 
        sort(b+1,b+6,cmp); 
        for(int i=5;i;i--){ 
            if(a[i].num==b[i].num) continue ; 
            return a[i].num>b[i].num; 
        } 
        for(int i=5;i;i--){ 
            if(a[i].col==b[i].col) continue ; 
            return a[i].col<b[i].col; 
        } 
        return 1; 
    } 
    bool cmp5(pii *a,pii *b){//顺子 
        if(a[1].num==1&&a[5].num==13){ 
            pii t=a[1];t.num=14; 
            for(int i=2;i<=5;i++) 
                a[i-1]=a[i]; 
            a[5]=t; 
        } 
        if(b[1].num==1&&b[5].num==13){ 
            pii t=b[1];t.num=14; 
            for(int i=2;i<=5;i++) 
                b[i-1]=b[i]; 
            b[5]=t; 
        } 
        /*for(int i=5;i;i--){ 
            if(a[i].num==b[i].num) continue ; 
            return a[i].num>b[i].num; 
        }*/
        if(a[1].num!=b[1].num) 
            return a[1].num>b[1].num; 
        for(int i=5;i;i--){ 
            if(a[i].col==b[i].col) continue ; 
            return a[i].col<b[i].col; 
        } 
        return 1; 
    } 
    bool cmp6(pii *a,pii *b){//三条 
        for(int i=1;i<=5;i++) 
            if(a[i].num==1) a[i].num=14; 
        for(int i=1;i<=5;i++) 
            if(b[i].num==1) b[i].num=14; 
        sort(a+1,a+6,cmp); 
        sort(b+1,b+6,cmp); 
          
        int sta; 
        for(int i=3;i<=5;i++) 
            if(a[i].num==a[i-1].num&&a[i].num==a[i-2].num){ 
                sta=i-2;break ; 
            } 
          
        int stb; 
        for(int i=3;i<=5;i++) 
            if(b[i].num==b[i-1].num&&b[i].num==b[i-2].num){ 
                stb=i-2;break ; 
            } 
          
        for(int i=sta+2,j=stb+2;i>=sta&&j>=stb;i--,j--){ 
            if(a[i].num==b[j].num) continue ; 
            else return a[i].num>b[j].num; 
        } 
          
        for(int i=5,j=5;i&&j;i--,j--){ 
            if(i==sta+2) i=sta-1; 
            if(j==stb+2) j=stb-1; 
            if(a[i].num==b[j].num) continue ; 
            else return a[i].num>b[j].num; 
        } 
          
        for(int i=sta+2,j=stb+2;i>=sta&&j>=stb;i--,j--){ 
            //printf("%d %d
    ",a[i].col,b[j].col); 
            if(a[i].col==b[j].col) continue ; 
            else return a[i].col<b[j].col; 
        } 
          
        for(int i=5,j=5;i&&j;i--,j--){ 
            if(i==sta+2) i=sta-1; 
            if(j==stb+2) j=stb-1; 
            if(a[i].col==b[j].col) continue ; 
            else return a[i].col<b[j].col; 
        } 
        return 1; 
          
    } 
    bool cmp7(pii *a,pii *b){//两对 
        for(int i=1;i<=5;i++) 
            if(a[i].num==1) a[i].num=14; 
        for(int i=1;i<=5;i++) 
            if(b[i].num==1) b[i].num=14; 
        sort(a+1,a+6,cmp); 
        sort(b+1,b+6,cmp); 
          
        pii pa1[3],pa2[3],pb1[3],pb2[3]; 
        bool f1=0,f2=0; 
        bool v1[6],v2[6]; 
        memset(v1,0,sizeof v1); 
        memset(v2,0,sizeof v2); 
        for(int i=2;i<=5;i++){ 
            if(a[i].num==a[i-1].num){ 
                if(f1) pa1[1]=a[i],pa1[2]=a[i-1]; 
                else pa2[1]=a[i],pa2[2]=a[i-1],f1=1; 
                v1[i]=v1[i-1]=1; 
            } 
              
            if(b[i].num==b[i-1].num){ 
                if(f2) pb1[1]=b[i],pb1[2]=b[i-1]; 
                else pb2[1]=b[i],pb2[2]=b[i-1],f2=1; 
                v2[i]=v2[i-1]=1; 
            } 
        } 
        if(pa1[1].num!=pb1[1].num) 
            return pa1[1].num>pb1[1].num; 
          
        if(pa1[2].num!=pb1[2].num) 
            return pa1[2].num>pb1[2].num; 
          
        if(pa2[1].num!=pb2[1].num) 
            return pa2[1].num>pb2[1].num; 
          
        if(pa2[2].num!=pb2[2].num) 
            return pa2[2].num>pb2[2].num; 
          
        for(int i=1;i<=5;i++)if(!v1[i]) 
            for(int j=1;j<=5;j++)if(!v2[j]){ 
                if(a[i].num!=b[j].num)  
                    return a[i].num>b[j].num; 
                break ; 
            } 
          
        if(pa1[1].col!=pb1[1].col) 
            return pa1[1].col<pb1[1].col; 
          
        if(pa1[2].col!=pb1[2].col) 
            return pa1[2].col<pb1[2].col; 
          
        if(pa2[1].col!=pb2[1].col) 
            return pa2[1].col<pb2[1].col; 
          
        if(pa2[2].col!=pb2[2].col) 
            return pa2[2].col<pb2[2].col; 
          
        for(int i=1;i<=5;i++)if(!v1[i]) 
            for(int j=1;j<=5;j++)if(!v2[j]){ 
                if(a[i].col!=b[j].col)  
                    return a[i].col<b[j].col; 
                break ; 
            } 
        return 1; 
    } 
    bool cmp8(pii *a,pii *b){//一对 
        for(int i=1;i<=5;i++) 
            if(a[i].num==1) a[i].num=14; 
        for(int i=1;i<=5;i++) 
            if(b[i].num==1) b[i].num=14; 
        sort(a+1,a+6,cmp); 
        sort(b+1,b+6,cmp); 
          
        int sta; 
        for(int i=2;i<=5;i++) 
            if(a[i].num==a[i-1].num){ 
                sta=i-1;break ; 
            } 
          
        int stb; 
        for(int i=2;i<=5;i++) 
            if(b[i].num==b[i-1].num){ 
                stb=i-1;break ; 
            } 
          
        for(int i=sta+1,j=stb+1;i>=sta&&j>=stb;i--,j--){ 
            if(a[i].num==b[j].num) continue ; 
            else return a[i].num>b[j].num; 
        } 
          
        for(int i=5,j=5;i&&j;i--,j--){ 
            if(i==sta+1) i=sta-1; 
            if(j==stb+1) j=stb-1; 
            if(a[i].num==b[j].num) continue ; 
            else return a[i].num>b[j].num; 
        } 
          
        for(int i=sta+1,j=stb+1;i>=sta&&j>=stb;i--,j--){ 
            //printf("%d %d
    ",a[i].col,b[j].col); 
            if(a[i].col==b[j].col) continue ; 
            else return a[i].col<b[j].col; 
        } 
          
        for(int i=5,j=5;i&&j;i--,j--){ 
            if(i==sta+1) i=sta-1; 
            if(j==stb+1) j=stb-1; 
            if(a[i].col==b[j].col) continue ; 
            else return a[i].col<b[j].col; 
        } 
        return 1; 
    } 
    bool cmp9(pii *a,pii *b){//无对 
        if(a[1].num==1){ 
            pii t=a[1];t.num=14; 
            for(int i=2;i<=5;i++) 
                a[i-1]=a[i]; 
            a[5]=t; 
        } 
        if(b[1].num==1){ 
            pii t=b[1];t.num=14; 
            for(int i=2;i<=5;i++) 
                b[i-1]=b[i]; 
            b[5]=t; 
        } 
        for(int i=5;i;i--){ 
            if(a[i].num==b[i].num) continue ; 
            else return a[i].num>b[i].num; 
        } 
        for(int i=5;i;i--){ 
            if(a[i].col==b[i].col) continue ; 
            else return a[i].col<b[i].col; 
        } 
        return 1; 
    } 
    int main(){ 
        getint(T); 
        while(T--){ 
            for(int i=1;i<=5;i++) 
                getint(Ail[i].num),getint(Ail[i].col); 
            for(int i=1;i<=5;i++) 
                getint(Muk[i].num),getint(Muk[i].col); 
            sort(Ail+1,Ail+6,cmp); 
            sort(Muk+1,Muk+6,cmp); 
            int t1=check(Ail); 
            int t2=check(Muk); 
            if(t1==t2){ 
                bool win; 
                if(t1==1) win=cmp1(Ail,Muk); 
                else if(t1==2) win=cmp2(Ail,Muk); 
                else if(t1==3) win=cmp3(Ail,Muk); 
                else if(t1==4) win=cmp4(Ail,Muk); 
                else if(t1==5) win=cmp5(Ail,Muk); 
                else if(t1==6) win=cmp6(Ail,Muk); 
                else if(t1==7) win=cmp7(Ail,Muk); 
                else if(t1==8) win=cmp8(Ail,Muk); 
                else if(t1==9) win=cmp9(Ail,Muk); 
                printf("%s
    ",win?"Alice":"Mukyu"); 
            } 
            else printf("%s
    ",t1<t2?"Alice":"Mukyu"); 
        } 
    } 

    周年纪念(anniversary)

    题目描述

    距离著名意大利数学家 Fibonacci 的 900 年诞辰纪念日还剩下不到 60 年。当然,这种重要的纪念日需要很多准备。

    Sidepi 认为应当解决以下问题来表达对 Fibonacci 的纪念:给定由 l、l+1、l+2……r 这 r-l+1 个整数构成的集合 A,考虑 A 的所有含有 k 个元素的子集;对于每个子集 B,设 Bi 是 能整除子集中全部 k 个元素的最大整数;i 是所有 Bi 的最大值,求第 i 个 Fibonacci 数 F[i] 是多少。 当然,Sidepi 也没忘记提醒你,F[1]=1,F[2]=1,F[n]=F[n-1]+F[n-2](n>=3)。 Sidepi 有半个多世纪的时间来解决这个问题,但是你只有 3 个半小时。因此你只需要输出 F[i] mod m 的值。

    输入格式

    四个用空格隔开的整数 m、l、r、k。 

    输出格式

    上述问题的答案 F[i] mod m 的值。 

    样例数据

    样例输入 样例输出
    10 1 8 2 3

    <数据范围>

    对于 50% 的数据,1<=l,r<=10^6;对于 100% 的数据,1<=m<=10^9,1 ≤ l < r ≤ 10^12,2 ≤ k ≤ r - l + 1。 

    解析

    [l,r]间i的倍数的个数等于r/i-(l-1)/i,随着i的增大r/i是减小的,(l-1)/i也是减小的,通过感觉我们知道r/i-(l-1)/i大体上也是减小的,但并不是严格递减,即使用二分+暴力也不能很有效地减小这个范围
    注意到从1开始一个个地枚举i是很不明智的,因为即使i++也很有可能不会使r/i和(l-1)/i中任意一项的值改变
    所以可以想到对于i来说min(l/(l/i),r/(r/i))是在保证r/i和(l-1)/i不变前提下的更优值,所以我们每次都只用枚举r/i和(l-1)/i一定时i的最优值即可,然后i++如此往复计算出下一个状态的最优值,可以证明在这个过程中我们一定会遍历到使r/i-(l-1)/i>=k成立最大的那个i
    这个做法很容易想出来,但是时间复杂度怎么保证呢……
    不妨假设在最gg的情况l=r=1e12,k=1
    那么i=1,2,3……r/3,r/2,r
    注意由于i只能为整数,所以i在一开始是很连续的,但是往后开始就不连续了,我们只要把这个临界点计算出来,然后就可以分段计算出时间复杂度了。

    我们可以假设第x次以及以后的分割都是按间隔为1均匀地分布的。
    n/x-n/(x-1)=1
    n*(x+1)=x*(x+1)+n*x
    n=x*(x+1)
    x=sqrt(n)
    时间复杂度:O(2*sqrt(n))

    Code

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    
    using namespace std;
    
    typedef long long ll;
    
    struct Mat{
        ll s[2][2];
        ll* operator [](const ll a){
            return s[a];
        }
    };
    Mat cv={0,1,1,1};
    Mat fib={0,1,0,0};
    
    ll m,l,r,w,x=1,y;
    Mat mul(Mat a,Mat b)
    {
        Mat s={0,0,0,0};
        for(ll i=0;i<2;i++)
            for(ll j=0;j<2;j++)
                for(ll k=0;k<2;k++)
                    s[i][j]+=a[i][k]*b[k][j]%m;
        return s;
    }
    Mat power(Mat a,ll b)
    {
        Mat s={1,0,0,1};
        while(b)
        {
            if(b&1)
                s=mul(s,a);
            a=mul(a,a);
            b/=2;
        }
        return s;
    }
    int main()
    {
        cin>>m>>l>>r>>w;
        l--;
        while(x<=r)
        {
            if((l/x)==0)
                x=r/(r/x);
            else
                x=min(l/(l/x),r/(r/x));
            if(r/x-l/x>=w)
                y=x;
            x++;
        }
        cv=power(cv,y);
        fib=mul(fib,cv);
        cout<<fib[0][0]<<endl;
        return 0;
    }

    Time: 2017-10-29

  • 相关阅读:
    vue day6 分页显示
    vue day5 分页控件
    vue day4 table
    c# excel xlsx 保存
    diff算法
    Web Workers
    多线程
    Http请求优化
    高效编写代码
    渲染引擎
  • 原文地址:https://www.cnblogs.com/SinGuLaRiTy2001/p/7750277.html
Copyright © 2020-2023  润新知