zoukankan      html  css  js  c++  java
  • 2016.8.24.noip2012D1

    vigenere:

    第一个比较简单的,就是个密码表,我直接把字母对应转化为数字,另一个bool数组确定大小写,然后根据规律写那个方程,完。

    game:

    事出反常必有妖。然而我之前并没有注意到。一开始就应该注意到,无论被除数还是除数之中都没有一个当前人的左手数。然后在考虑总积不变的规律就应该联想到,通过排列左手右手数的乘积来判断。然而本题之中前一个思路为一点,另一个更重要的地方时数据范围需要使用高精度对单精度的除法、乘法,并且由于数据过大,最好使用万进制。

    个人修改后代码如下(并未使用万进制):

    #include<iostream>
    #include<cstring>
    #include<fstream>
    #include<algorithm>
    #define cin fin
    using namespace std;
    ifstream fin ("game.in");
    ofstream fout ("game.out");
    int n,a0,b0,ans[4405],p[4406],prod[4405],divi[4405];
    struct stu
    {
        int a,b,c;
    }f[1005];
    bool yeah(const stu & q1,const stu &q2)
    {
        return q1.c<q2.c;
    }
    void pro(int x)
    {
        int t=0,i9=0;
        memset(p,0,sizeof(p));
        p[0]=prod[0];
        for(int i8=1;i8<=prod[0];i8++)
        {
            t=x*prod[i8];
            p[i8]+=t;//万一多位进位
            i9=i8;
            while(p[i9]>=10)
            {
                p[i9+1]+=p[i9]/10;
                p[i9]%=10;
                i9++;
            } 
            if(i9>p[0])//防止出现42500005而p[0]=3时的特殊情况。 
            p[0]=i9;
        }
        prod[0]=p[0];
        while(p[0])
        prod[p[0]]=p[p[0]],p[0]--;
    }
    void div(int x)
    {
        divi[0]=prod[0];
        int y=0;
        for(int i8=prod[0];i8>0;i8--)
        {
            y=prod[i8]+10*y;
            divi[i8]=y/x;
            y=y%x;
        }
        while(divi[divi[0]]==0&&divi[0]>1) divi[0]--;
    }
    int main()
    {
        cin>>n;
        cin>>a0>>b0;
        for(int i=1;i<=n;i++)
        {
            cin>>f[i].a>>f[i].b;
            f[i].c=f[i].a*f[i].b;
        }
        sort(f+1,f+n+1,yeah);
        prod[1]=prod[0]=1;
        pro(a0);
        for(int i=1;i<=n;i++)
        {
            div(f[i].b);
            pro(f[i].a);
            int o=-1;
            if(divi[0]>=ans[0])
            {
                if(ans[0]==divi[0]) o=0;
                ans[0]=divi[0];
                for(int j=divi[0];j>0;j--)
                {
                    if(o==0) 
                    if(ans[j]<divi[j]) o=1;
                    else if(ans[j]>divi[j]) break;
                    ans[j]=divi[j];
                }
            }
        }
        for(int i=ans[0];i>0;i--)
        fout<<ans[i];
        return 0;
    }

    根据此情况,发现高精度算法还需要复习,并且最好使用模板。

    drive:

    这道题,一开始并没有想到从后往前处理顺序问题(方便查找最近和第二近的),而是愚蠢的用了两个二分查找,费时费力。

    之后呐,也并没有想到更好的办法。

    后面的处理是用的并不太好的倍增。简直迷醉。倍增次数,不清楚这些人怎么想出来的。

    之后倍增总结的时候一并算了吧。

  • 相关阅读:
    Execution Contexts (执行上下文)
    OOP—ECMAScript实现详解
    requireJS入门
    SqlServer 傲娇的表变量
    CSharp进阶 引用类型引发的血案
    CSharp进阶 都是请求惹的祸
    z-index问题
    js中事件(自定义事件)
    做了个后末日朋克风的梦
    昨晚的梦
  • 原文地址:https://www.cnblogs.com/fisch/p/5805334.html
Copyright © 2011-2022 走看看