zoukankan      html  css  js  c++  java
  • 鸽巢原理

    鸽巢原理入门

    题目传送门:点击打开链接

    Find a multiple
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 7055   Accepted: 3086   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
    

    Source

    先引入鸽巢原理概念:
    鸽巢原理,又名狄利克雷抽屉原理、鸽巢原理。

    其中一种简单的表述法为:若有n个笼子和n+1只鸽子,所有的鸽子都被关在鸽笼里,那么至少有一个笼子有至少2只鸽子。

    百度鸽巢原理视频,竟然所有的都是为了小学生准备的,真是欲哭无泪!

    本题的意思很简单,给n个数,从中任意选出若干个数,求和,要求其满足是n的倍数。这里说明一下,任意n个数是必然能够找的到若干个数求其和满足整除n。证明:从第一个数开始依次求和保存于Sk中,那么S1到Sn mod n在1-n之间,根据鸽巢原理得知必然有两个Si、Sj mod n的结果相同,则(Sj%n)==(Si%n)==>(Sj-Si)%n == 0即可求出题中所述结果。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <string>
    #include <algorithm>
    #include <stack>
    #include <set>
    using namespace std;
    
    typedef long long int LL ;
    
    int a[10010];
    LL s[10010];		//求和数组结果 
    int b[10010];		//保存其和余数 
    int c[10010];		//标记数组 
    
    
    
    int main() {
    	int n;
    	cin >> n;
    	memset(a, 0, sizeof(a));
    	for (int i = 1; i<=n; i++)
    		cin >> a[i];
    	memset(s, 0, sizeof(s));
    	for (int i = 1; i<=n; i++) {		//扫描求和,若遇到满足答案则结束 
    		s[i] = s[i-1] + a[i];
    		if (s[i] %n == 0) {
    			cout << i<< endl;
    			for (int j = 1; j<=i; j++) 
    				cout << a[j]<< endl;
    			return 0;
    		}
    		//cout << s[i]<< endl;
    	}
    	//cout << endl;
    	memset(b, 0, sizeof(b));
    	memset(c, 0, sizeof(c));
    	int flag = 1;
    	int i;
    	for (i = 1; i<=n && flag; i++) {		//求和取余保存 
    		b[i] = s[i] %n;
    		c[b[i]] ++ ;
    		//cout << b[i]<< endl;
    		if (c[b[i]] > 1) {
    			break;
    			flag = 0; ;
    		}
    	}
    	//cout << i<< endl;
    
    	int j;
    	for (j = 1; j<=n; j++) {
    		if (b[j] == b[i])
    			break;
    	}
    	//cout << j<< endl;
    	cout << i-j<< endl;
    	for (int k = j+1; k<=i; k++)
    		cout << a[k] << endl;
    	return 0 ;
    }

    积累!!积累、思考、总结、坚持





  • 相关阅读:
    例图作业
    冲刺第二天
    Day9
    Day8
    Day7
    Day6
    Day5
    Day4
    Day2
    第四次作业——个人作业——软件案例分析
  • 原文地址:https://www.cnblogs.com/Tovi/p/6194847.html
Copyright © 2011-2022 走看看