noip2012 day1

Vigenère密码

 

 

字符串的一个模拟,核心在于判断大小写(?)

#include<bits/stdc++.h> 
using namespace std;
char k[10002],m[10002];
int main() 
{
    gets(k);
    gets(m);
    int l1=strlen(k);
    int l2=strlen(m);
    for(int i=0;i<l1;i++)
    {
        if(isupper(k[i]))
          k[i]=tolower(k[i]);
    }
    int j=0;
    for(int i=0;i<l2;i++) 
    {
        if(islower(m[i])) 
        {
            m[i]=char(m[i]-(k[j++]-'a'));
            if(m[i]<'a')
            m[i]=char(m[i]+26);
        }
        else 
        {
            m[i]=char(m[i]-(k[j++]-'a'));
            if(m[i]<'A')
            m[i]=char(m[i]+26);
        }
        if(j>=l1)
        j=0;
    }
    printf("%s",m);
}

国王游戏

 

 

 

 

贪心+高精度

首先,贪心策略:左右手乘积越小放越前面

策略证明:

a,b两人,左右手乘积为s,左手l,右手r

假设a在b前面比b在a前面更优

a在b前面时:

a所得为sa/la  ……1'

b所得为sa*la*sb/rb  ……2'

b在a前面时:

a所得为sb*lb*sa/ra  ……3'

b所得为sb/lb  ……4'

要使得假设成立,即:max(1',2')<max(3',4')

又显然,1'<3',2'<4'

所以化简即可得:la*ra<lb*rb

再在贪心基础上加上高精度就可以AC啦

但是高精度实在是难打啊,不打还能有60分,也是挺良心的

60分代码

#include <bits/stdc++.h>
using namespace std; 
#define ll long long
struct node 
{ 
    int x,y; 
}q[1003];

bool cmp(node aa, node bb) 
{
    return aa.x*aa.y<bb.x*bb.y; 
}

int main() 
{
    int n,a,b;
    scanf("%d%d%d",&n,&a,&b);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&q[i].x,&q[i].y);
    }
    ll k=a; 
    sort(q+1,q+n+1,cmp); 
    ll ans=0;
    for(int i=1;i<=n;i++) 
    {
        ans=max(ans,k/q[i].y); 
        k*=q[i].x; 
    }
    printf("%lld", ans); 
    return 0; 
}

100分代码

#include<bits/stdc++.h>
using namespace std;
int now[20010],sum[20010],ans[20010],add[20010];
struct node 
{
    int x;
    int y;
}q[10005];

void gjd1(int xx) 
{
    memset(add,0,sizeof(add));
    for(int i=1;i<=ans[0];i++) 
    {
        ans[i]=ans[i]*xx;
        add[i+1]+=ans[i]/10;
        ans[i]%=10;
    }
    for(int i=1;i<=ans[0]+4;i++) 
    {
        ans[i]+=add[i];
        if(ans[i]>=10) 
        {
            ans[i+1]+=ans[i]/10;
            ans[i]%=10;
        }
        if(ans[i]!=0) 
        {
            ans[0]=max(ans[0],i);
        } 
    }
    return ;
}

int gjd2(int xx) 
{
    memset(add,0,sizeof(add));
    int u=0;
    for(int i=ans[0];i>=1;i--) 
    {
        u*=10;
        u+=ans[i];
        add[i]=u/xx;
        if(add[0]==0&&add[i]!=0) 
        {
            add[0]=i;
        }
        u%=xx; 
    }
    return 0;
}

bool compare() 
{
    if(sum[0]==add[0]) 
    {
        for(int i=add[0];i>=1;i--) 
        {
            if(add[i]>sum[i]) return 1;
            if(add[i]<sum[i]) return 0;
        }
    }
    if(add[0]>sum[0]) return 1;
    if(add[0]<sum[0]) return 0;
}

bool cmp(node aa,node bb) 
{
    return aa.x*aa.y<bb.x*bb.y;
}

int main() 
{
    int n,a,b;
    scanf("%d%d%d",&n,&a,&b);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&q[i].x,&q[i].y);
    }
    sort(q+1,q+n+1,cmp);
    q[0].x=a,q[0].y=b; 
    ans[0]=1,ans[1]=1;
    for(int i=1;i<=n;i++) 
    {
        gjd1(q[i-1].x);
        gjd2(q[i].y);
        if(compare()) 
        {
            for(int i=add[0];i>=0;i--) 
            {
                sum[i]=add[i];
            }
        }
    }
    for(int i=sum[0];i>=1;i--)
    printf("%d",sum[i]);
    return 0;
}

开车旅行

 

 

 

 

 

 

倍增,但是预处理很麻烦

嗯还没打出来,留个坑,以后来填……

posted @ 2020-04-05 20:35  mgtnb  阅读(138)  评论(0编辑  收藏  举报