zoukankan      html  css  js  c++  java
  • hust Little Sheep and a paper

    http://acm.sdibt.edu.cn:8080/judge/contest/view.action?cid=573#problem/H

    题意:一张纸对折(向前翻),可以向左向右向上向下,经过几次对折,问起面向你的突出的折痕有多少个

    分析1:经过折叠很容易清楚LR是一样的,UD是一样的。

             当该次折叠的是LR,则row[i]=row[i-1]*2;纵向折一次,那么前一次的横向就要翻倍

                                            col[i]=col[i-1]+face/2;前一次的纵向就会增加纸的厚度/2;

    这里出现的问题就是对于face的取余,因为face必定是偶数,而取模后很难保证其face就一定是偶数,而且对于/2叶很难保证其正确性

     若其为奇数,/2会取证,所以我的思路就是舍弃其face/2这个步骤,直接记录其前一次的值

    View Code
    #include<stdio.h>
    #include<string.h>
    const int MN=1000010;
    const long long MOD=100000009;
    
    char str[MN];
    
    int main()
    {
    long long row[2],col[2],face[2];
        int i,j;
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%s",str);
            memset(row,0,sizeof(row));
            memset(col,0,sizeof(col));
            int t=1;
            face[0]=1;
            face[1]=0;
            for(i=0;str[i];i++)
            {
                if(str[i]=='L' || str[i]=='R')
                {
                    row[t]=(row[1-t]*2)%MOD;
                    col[t]=(col[1-t]+face[t])%MOD;
                }
                else
                {
                    row[t]=(row[1-t]+face[t])%MOD;
                    col[t]=(col[1-t]*2)%MOD;
                }
                face[t]=(face[1-t]*2)%MOD;
                t=1-t;
            }
            t=1-t;
            printf("%lld\n",(row[t]+col[t])%MOD);
        }
        return 0;
    }

    分析2:看了别人的思路,试了他的代码,其时间效率整整比我少1000ms

               假设其只折叠LR,则其纵向的个数s1=(2^n1)-1,同理只折叠UD,其横向的个数s2=(2^n2)-1

               若交叉折叠的话,横向就是(s1+1)*s2,例如当纵向折叠一次,则横向*2 ,纵向折叠两次,则横向*4 纵向折叠三次,则横向*8

               当然,要排除掉第一次的折叠(无论第一次折叠式LR还是UD,对于其后的次数都没有影响,也就是说第一次的折叠应该忽略不计)

    View Code
    #include<stdio.h>
    #include<string.h>
    const int MN=1000010;
    const long long MOD=100000009;
    
    char str[MN];
    
    long long pow_mod(long long a, long long n, long long m)
    {
        if(n==0) return 1;
        if ( n == 1 ) return a % m;
        long long x = pow_mod(a, n / 2, m);
        long long  ans = x * x % m;
        if ( n % 2 == 1 ) ans = (ans * a) % m;
        return ans;
    }
    
    int main()
    {
        long long row,col,s1,s2;
        int i,j,flag;
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%s",str);
            row=col=0;
            for(i=0; str[i]; i++)
            {
                if(str[i]=='L' || str[i]=='R') col++;
                else row++;
            }
            if(str[0]=='L' || str[0]=='R') flag=1;
            else flag=0;
            if(!flag)
            {
                int tmp=col;
                col=row;
                row=tmp;
            }
            col--;
            s1=pow_mod(2,col,MOD);
            s2=pow_mod(2,row,MOD);
            printf("%lld\n",((s1-1)*s2%MOD+(s2-1)*s1%MOD)%MOD);
        }
        return 0;
    }
  • 相关阅读:
    Microsoft.Office.Interop.Excel 组件的报错检索 COM 类工厂中 CLSID,错误码:80070005
    SQLServer编写自己的切分函数 SPLIT和带排序的切割函数 SPLITSort
    Powerdesigner 导出Excel格式数据字典 导出Excel格式文件
    NPOI 导入导出excel两种方式 和 错误 无法访问已关闭的流解决方式
    unable to start the virtual device;Genymotion启动安卓模拟器出错
    datetimepicker 时间控件 1899年问题以及解决方法
    Linux命令大全
    Linux工具包
    Redis
    MySQL索引
  • 原文地址:https://www.cnblogs.com/zsboy/p/2951690.html
Copyright © 2011-2022 走看看