Stay Hungry,Stay Foolish!

1032. Find a Multiple

1032. Find a Multiple

https://acm.timus.ru/problem.aspx?space=1&num=1032

 

思路

对于n个数 a[1] ... a[n]

首先计算累加和 s[1] ... s[n]

s[i] = a[1] + a[2] + ... + a[i]

 

如果累加和中有一项是n的倍数, 则s[i] % n == 0, 找到答案

如果所有累加和s[1] ... s[n]都不是n的倍数, 则 s[1]%n ... s[n]%n的值都不是0, 其范围是[1, n-1]

n个数,对应范围只有n-1个, 鸽笼原理知道, 必然有一对 i 和 j 使得 s[i]%n == s[j]%n

统计所有的 s[i]%n 值, 找出i 和 j

code

int n;
int a[10005];
int s[10005];

int main()
{
    cin >> n;
    
    for(int i=1; i<=n; i++){
        cin >> a[i];
    }

    s[1] = a[1];
    for(int i=2; i<=n; i++){
        s[i] = s[i-1] + a[i];
    }

    for(int i=1; i<=n; i++){
        if(s[i] % n == 0){
            cout << i << endl;
            for(int j=1; j<=i; j++){
                cout << a[j] << endl;
            }
            return 0;
        }
    }

    /*
    here means s[i] % n all not equal 0
    so s[1] % n , ... , s[n] % n > 0
    they are in the range of [1, n]
    but there are n item of s[i]
    so there must be i and j, meets
    s[i] % n == s[j] % n
    */

    map<int, int> flag;
    for(int i=1; i<=n; i++){
        int rem = s[i] % n;
        
        // previous index has the same remainer with i
        int previ = flag[rem];
        if (previ != 0){
            int mini = min(previ, i);
            int maxi = max(previ, i);
            int count = maxi - mini;
            cout << count << endl;
            for(int j=mini+1; j<=maxi; j++){
                cout << a[j] << endl;
            }
            return 0;
        } else {
            flag[rem] = i;
        }
    }

    return 0;
}

 

posted @ 2023-01-10 22:35  lightsong  阅读(20)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel