您的位置:首页 > 其它

抽屉定理poj 3370|| hdu1808 Halloween treats || hdu 1205 吃糖果 ||poj 2356

2015-07-29 17:42 453 查看
hdu 1808 || poj 3370原题链接:点击打开链接

思路(转):

首先简单说一下鸽巢原理,就是有n+1个球,放在n个盒子中,那么至少有一个盒子有两个或更多的球。

而这两道题正是运用了这个思想。先对数列求前N项和,有s1=a1,s2=a1+a2,

s3=a1+a2+a3,......,sn=a1+a2+a3+...+an。若其中有和可以整除m,那么即可得出答案,否则,所得的余数只会是1,2,...,n-1,因此,必存在至少两个数模除m后有相同余数r,即si=b*m+r,sj=c*m+r,则si-sj=(b-c)*m。则序列ai到aj的和即为所求。
code:
#include<stdio.h>
#include<string.h>
int yushu[100010],d[100010];
int main()
{
    int m,i,j,ans,c,n,sum;
    while(scanf("%d%d",&c,&n)!=EOF)
    {
        if(c==0&&n==0)
            break;
            memset(yushu,0,sizeof(yushu));
        for(i=1;i<=n;i++)
            scanf("%d",&d[i]);
        int st,ed;
        sum=0;
        for(i=1;i<=n;i++)
        {
            sum=(sum+d[i])%c;
            if(sum==0)
            {
                st=1;
                ed=i;
                break;
            }
            else if(yushu[sum])
            {
                st=yushu[sum]+1;
                ed=i;
                break;
            }
            else
                yushu[sum]=i;
        }
        for(i=st;i<=ed;i++)
        printf(i==ed?"%d\n":"%d ",i);

    }
    return 0;
}


hdu 1205:

原题链接:点击打开链接

思路:找出数量最多的某类糖果(m个),剩下sum-m个,则能产生(sum-m+1)个位置来放置数量最多的糖果

如果m>(sum-m+1)则说明不能将数量最多的吃完,反过来看,m个数量最多的某类糖果,相当于有m块挡板,产生了m+1个空格可以用来放置其余的糖果,这些数量不太多的糖果 也可以看做是将之前产生的挡板的厚度增加的。

比如 :m1x1n1 m2n2 m3n3
m4n4 m5n5;

其中 x1就相当于将前一个挡板加厚了 只要能保证数量最多的糖果被吃完 就能被吃完

code:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
int main()
{

    int cas;
    scanf("%d",&cas);
    __int64 n,maxx,sum,i,t;
    while(cas--)
    {
        sum=0;
        maxx=-1;
        scanf("%I64d",&n);
        for(i=0;i<n;i++)
        {
            scanf("%I64d",&t);
            sum+=t;
            maxx=max(maxx,t);
        }
        if(maxx>(sum-maxx+1))
            printf("No\n");
        else
            printf("Yes\n");
    }
    return 0;
}


poj 2356:与poj3370 一样 除了输出之外。

code:

#include<stdio.h>
#include<string.h>
int d[10010],yushu[10010];
int main()
{
    int i,sum=0,st,ed,n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(yushu,0,sizeof(yushu));
        for(i =1 ;i<=n;i++)
            scanf("%d",&d[i]);
        for(i=1;i<=n;i++)
        {
            sum=(sum+d[i])%n;
            if(sum==0)
            {
                st=1;
                ed=i;
                break;
            }
            else if(yushu[sum])
            {
                st=yushu[sum]+1;
                ed=i;
                break;
            }
            else
                yushu[sum]=i;
        }
        printf("%d\n",ed-st+1);
        for(i=st;i<=ed;i++)
            printf("%d\n",d[i]);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: