8 27 組隊賽 Greater New York 2012

caoxiaoran1202發表於2013-08-29

題目來源 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專題。 

相關文章