zoukankan      html  css  js  c++  java
  • POJ- Find a multiple -(抽屉原理)

    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 6452   Accepted: 2809   Special Judge

    Description

    The input contains N natural (i.e. positive integer) numbers ( N <= 10000 ). Each of that numbers is not greater than 15000. This numbers are not necessarily different (so it may happen that two or more of them will be equal). Your task is to choose a few of given numbers ( 1 <= few <= N ) so that the sum of chosen numbers is multiple for N (i.e. N * k = (sum of chosen numbers) for some natural number k).

    Input

    The first line of the input contains the single number N. Each of next N lines contains one number from the given set.

    Output

    In case your program decides that the target set of numbers can not be found it should print to the output the single number 0. Otherwise it should print the number of the chosen numbers in the first line followed by the chosen numbers themselves (on a separate line each) in arbitrary order. 

    If there are more than one set of numbers with required properties you should print to the output only one (preferably your favorite) of them.

    Sample Input

    5
    1
    2
    3
    4
    1
    

    Sample Output

    2
    2
    3
     1 /*这题在于对抽屉原理的应用,输入一个数N,然后有N行,每一行输入一个数,*/
     2 /*求是否存在连续和能够整除N的数,并且输出该数的个数以及连续数*/
     3 /*
     4 抽屉原理:主要是用来求数列的某一段连续和能够整除该数列个数的问题;
     5 先累每一个数,记录在Sum中,设i>j,则sum[i]-sum[j]则表示位置i到位置j这一段区间的和,
     6 题目既可以简化为求(sum[i]-sum[j])%N==0的满足条件即可
     7 所以设q,p(倍数),r1,r2(余数)为整数,
     8 sum[i]=q*N+ri,sum[i]=p*N+rj;
     9 ri=Sum[i]%N (ri为余数)
    10 (sum[i]-sum[j])=>(q*N+ri)-(p*N+rj)=>(q-p)*N+(ri-rj)
    11 既为:(sum[i]-sum[j])%N==0=>((q-p)*N+(ri-rj))%N==0
    12         =>(ri-rj)%n==0=>ri=rj可以使得等式成立,可满足条件;
    13 所以只需要求解存在两个ri和rj相等,就可以知道,该段位置从i+1累加到j能够被N整除
    14 */
    15 #include <stdio.h>
    16 #include <stdlib.h>
    17 #include <string.h>
    18 int main()
    19 {
    20     int Num[100860];    /*记录输入数据*/
    21     int Sum[100860];    /*记录数据的累加和*/
    22     int Sign[100860];   /*记录该数据累加和取余后的情况,sign[i],0<=i<N*/
    23     int ID[100860];     /*ID[i]表示该余数是否被出现过了,记录每一个余数第一次产生i的位置,且ID[0]=0*/
    24     int Begin,End,Flat,i,N;     /*Flat标记是否完成任务*/
    25     while(scanf("%d",&N)!=EOF)
    26     {
    27         memset(Sum,0,sizeof(Sum));  
    28         memset(ID,-1,sizeof(ID));   /*因为ID存放的是该数的位置,需要初始化为-1,*/
    29         ID[0]=0;/*记得标记初始位置的*/
    30         for(i=1,Flat=1;i<=N;i++)
    31         {
    32             scanf("%d",&Num[i]);
    33             Sum[i]=Sum[i-1]+Num[i]; /*求累加和*/
    34             Sign[i]=Sum[i]%N;       /*求累加和的余数*/
    35             if(ID[Sign[i]]>=0&&Flat)    /*判断该位置是否被使用过,且是否完成任务*/
    36             {
    37                 Begin=ID[Sign[i]];  /*记录开始点*/
    38                 End=i;              /*记录结束点*/
    39                 Flat=0;
    40             }
    41             else if(Flat)
    42                 ID[Sign[i]]=i;      /*如果该余数未被产生,则记录下该余数第一次出现的位置*/
    43         }
    44         printf("%d
    ",End-Begin);
    45         for(i=Begin+1;i<=End;i++)
    46         {
    47             printf("%d
    ",Num[i]);
    48         }
    49 
    50     }
    51     return 0;
    52 }
    View Code
    转载请备注:
    **************************************
    * 作者: Wurq
    * 博客: https://www.cnblogs.com/Wurq/
    * Gitee: https://gitee.com/wurq
    **************************************
  • 相关阅读:
    Thinking in java(八)-正则表达式
    order by与索引
    order by与索引
    004_常量的设置
    008_ajax没有跳转页面的错误
    007_缺少aspactj依赖
    006_为什么我的本机地址是0.0.0.0.0.1
    005_mybatis逆向工程错误
    004_当用数据库账号密码不对时?
    059_SSM——JDK动态代理是怎么回事?它又是怎么运用到了SSM框架中的?
  • 原文地址:https://www.cnblogs.com/Wurq/p/4361247.html
Copyright © 2011-2022 走看看