POJ 2356 Find a multiple / 3370 Halloween treats 鸽巢原理

来源:互联网 发布:怎么登陆支付宝知托付 编辑:程序博客网 时间:2024/06/06 10:04

题意:给定n个正整数,从中任意的选出一些数,使他们的和能够被n整除。

题解:《组合数学》P17

#include<cstdio>#include<cstring>using namespace std;const int MAXN = 20000;int sum[MAXN], num[MAXN], flag[MAXN];void print ( int s, int t ){    printf("%d\n", t - s + 1);    for ( int i = s; i <= t; i++ )        printf("%d\n",num[i]);}int main(){    int n, i;    scanf("%d",&n);    for ( sum[0] = 0, i = 1; i <= n; i++ )    {        scanf("%d",&num[i]);        sum[i] = sum[i-1] + num[i];    }    memset(flag,0,sizeof(flag));    for ( i = 1; i <= n; i++ )    {        int t = sum[i] % n;        if ( t == 0 ) { print ( 1, i ); break; }        if ( flag[t] ) { print ( flag[t] + 1, i ); break; }        flag[t] = i;    }    return 0;}

下面是3370

#include<cstdio>#include<cstring>using namespace std;#define lint __int64const int MAXN = 110000;lint sum[MAXN];int num[MAXN], flag[MAXN];void print ( int s, int t ){    for ( int i = s; i < t; i++ )        printf("%d ",i);    printf("%d\n",t);}int main(){    int c, n, i;    while ( scanf("%d%d",&c,&n) )    {        if ( !c && !n ) break;        for ( sum[0] = 0, i = 1; i <= n; i++ )        {            scanf("%d",&num[i]);            sum[i] = sum[i-1] + num[i];        }        int start, end, t, f = 0;        memset(flag,0,sizeof(flag));        for ( i = 1; i <= n && !f; i++ )        {            t = sum[i] % c;            if ( t == 0 && sum[i] >= c )            {                start = 1, end = i; f = 1; break;            }            if ( flag[t] && sum[i] - sum[flag[t]] >= c )            {                start = flag[t] + 1, end = i, f = 1; break;            }            flag[t] = i;        }        if ( f ) print (start, end);        else printf("no sweets\n");    }    return 0;}


原创粉丝点击