8 27 组队赛 Greater New York 2012

题目来源 hdu4484 --  4492

hdu4484   最水的一道,直接一直找到1为止

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int a[11000];
int main()
{
    int N;
    int n;
    scanf("%d",&N);
    for(int i=1;i<=N;i++)
    {
        scanf("%d%d",&i,&n);
        if(n==1)
            printf("%d 1\n",i);
        else
        {
            int j=1;
            a[0]=n;
            while(j>0)
            {
                if(n%2==0)
                    n=n/2;
                else
                    n=3*n+1;
                a[j]=n;
                if(a[j]==1)
                    break;
                j++;
            }
            sort(a,a+j+1);

            printf("%d %d\n",i,a[j]);
        }
    }
    return 0;
}


hdu 4485

找规律,就是给定一个长度在10000以内的数字串,用b进制表示的,让求这个b进制表示的数字串%(b-1)   

规律就是数字串各个数字之和%(b-1)。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
char s[10000005];
int main()
{
    int T;
    scanf("%d",&T);
    int b;
    for(int i=1;i<=T;i++)
    {
        scanf("%d%d",&i,&b);
        getchar();
        gets(s);
        int len=strlen(s);
        int ans=0;
        for(int j=0;j<len;j++)
        {
            ans+=(s[j]-'0');
            //cout<<"hfhhf:"<<ans<<endl;
        }
        printf("%d %d\n",i,ans%(b-1));
    }
    return 0;
}


 

hdu 4486

题意:让求三角形的个数,若三边互不相等,按两个算。

一定要找对方法,不然就会TLE。

我一开始枚举两条边用了两个for循环,果断TLE.

后来想到枚举一条最小边,最大边范围就确定了,但是等边和等腰还是不好去判断。

再后来就是等边和等腰提前判断,然后枚举一条最小边,确定最大边范围,使得a、b、c互不相等就行了。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int main()
{
    int T;
    scanf("%d",&T);
    int n;
    for(int i=1;i<=T;i++)
    {
        int a,b,c;
        scanf("%d%d",&i,&n);
        int ans=0;
        for(int a=n/4;a<=n/2;a++) //等腰或等边
        {
            if(2*a>n-2*a&&a+a<n)
            ans++;
        }
       // cout<<"ans:"<<ans<<endl;
        for(a=1;a<=n/3;a++)
        {
            int l=(n-a)/2+1;
            int r=n-2*a-1;
            if(n%2==0)
                r=min(r,n/2-1);
            else
                r=min(r,n/2);
            if(r>=l)
                ans+=(r-l+1)*2;
        }
    }
    return 0;
}


 hdu 4488

一道模拟题,只要将400*400的矩阵数字模拟出来就行了。

注意一点就是0的处理,为0时,将分子置为0,分母为1,即0/1,这样不影响通分操作,因为0和非0整数的最大公约数为1.  这个建议是大神提供的,自己没想到,经验太少。

交题还犯二了,hdu上只认__int64,  bnu上认long long      计算每一行的第一个数时,要边约分边加和。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
struct node
{
    __int64 n;
    __int64 d;
} s[500][500];
__int64 gcd(__int64 m,__int64 n)
{
    if(n==0)
        return m;
    else
        return gcd(n,m%n);
}
void solve()
{
    s[0][1].n=1;
    s[0][1].d=1;
    for(int i=1; i<=400; i++)
    {
        for(int j=i+1; j>=1; j--)
        {
            if(j!=1)
            {
                __int64 dd=gcd(i*abs(s[i-1][j-1].d),j*abs(s[i-1][j-1].n));
                s[i][j].d=(s[i-1][j-1].d)*i/dd;
                s[i][j].n=(s[i-1][j-1].n)*j/dd;
            }
            else if(j==1)
            {
                __int64 a=s[i][i+1].n;
                __int64 b=s[i][i+1].d;
                __int64 aa=a;
                __int64 bb=b;
                for(int j1=i; j1>1; j1--)
                {
                    aa=a*s[i][j1].n;
                    bb=b*s[i][j1].n+a*s[i][j1].d;
                    __int64 gg=gcd(abs(aa),abs(bb));
                    a=aa/gg;
                    b=bb/gg;
                }
                __int64 rr=gcd(aa,abs(aa-bb));
                s[i][1].n=aa/rr;
                s[i][1].d=(aa-bb)/rr;
                if(s[i][1].d==0)
                    s[i][1].n=1;
            }
        }
    }
}
int main()
{
    solve();
    int T;
    scanf("%d",&T);
    for(int i=1; i<=T; i++)
    {
        int x,y;
        scanf("%d%d%d",&i,&x,&y);
        if(s[x][y].d==0)
            printf("%d 0\n",i);
        else if(s[x][y].n==1)
            printf("%d %I64d\n",i,s[x][y].d);
        else
            printf("%d %I64d/%I64d\n",i,s[x][y].d,s[x][y].n);
    }
    return 0;
}


 

hdu 4489

题意:有n个身高互不相等的士兵,排成一排,只能按如下规律排列:一个士兵比他两边的士兵都低,或者都高。

           如:有四个士兵,身高1、2、3、4     排列1 3 2 4  符合要求,3比1、2都大, 2比3 ,4 都小。

解题思路:最重要的是要了解一点:n个士兵的排列只能!!是第2个比1,3个都高,然后第3个比2,4个都低,然后第4个比3,5个都高。。。。。。。

                                                                                            !!!!或第2个比1,3个都低,然后第3个比2,4个都高,然后第4个比3,5个都低。。。。。。。

                  两种排列方式的数目是相等的。

                  求n,个人的排列可由前面求出的1-n-1个人的排列求出,  按第n个人的位置来求,他左边可能有0,1,。。。n-1个人

                  左边有0个人,右边n-1个人排列方式只能是!!这种排列,有f[n-1]/2中,依次求

                  。。。。。。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
long long f[22];
__int64 g[22];
long long ff() //求阶乘
{
    f[1]=1;
    for(int i=2;i<=20;i++)
        f[i]=f[i-1]*i;
}
long long C(int n,int m) //求组合数
{
    return f[n]/f[m]/f[n-m];
}
void solve()
{
    g[1]=1;
    g[2]=2;
    for(int i=3;i<=20;i++)
    {
        g[i]+=g[i-1];  //第i个人左边或右边有0个人
        g[i]+=(g[i-2]*(i-1));  //第i个人左边或右边有1个人
        for(int j=2;j<=i-3;j++)  //第i个人左边有j个人
            g[i]+=((g[j]*g[i-j-1]/4)*(C(i-1,j)));  //因为j个人的排列有一半符合要求,
                                                   //j-i-1个人的排列也只有一半符合要求,所以除4.
    }
}
int main()
{
    ff();
    solve();
    int T;
    scanf("%d",&T);
    int q;
    for(int i=1;i<=T;i++)
    {
        scanf("%d%d",&i,&q);
        printf("%d %I64d\n",i,g[q]);
    }
    return 0;
}


 

hdu 4492

理解了题意,很简单,只是我读了三遍才懂

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
char s[100];
char ss[600];
int b[600];
int main()
{
    int T;
    int n;
    scanf("%d",&T);
    for(int i=1;i<=T;i++)
    {
        scanf("%d",&i);
        getchar();
        gets(s);
        int len=strlen(s);
        scanf("%d",&n);
        int d=0;
        for(int j=0;j<n;j++)
        {
            scanf("%d",&b[j]);
        }
        d=0;
        for(int j=0;j<n;j++)
        {
            d=d+b[j];
            if(d>=len)
                d=d%len;
            if(d<0)
                d=len+d;
            ss[j]=s[d];
        }
        ss[n]='\0';
        printf("%d ",i);
        puts(ss);
    }
    return 0;
}


hdu 4487

请看DP专题。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值