问题描述
AK有一盒珠子共n颗,编号1到n。他一不小心将盒子打翻,所有珠子都散落在地。他一颗一颗地把珠子捡起来,每捡一颗就记录下当前这颗珠子的编号。捡完以后发现少了两颗,请你快速找出少了哪两颗珠子。
输入格式
第一行,一个整数n
接下来一行,n-2个空格间隔的整数,表示何老板捡起来的珠子的编号。输出格式
一行,由小到大排列的两个整数,表示丢失的两颗珠子的编号。
样例输入 1
7
4 1 7 2 5样例输出 1
3 6
样例输入 2
10
4 5 8 3 9 7 1 2样例输出 2
6 10
提示
时间限制 : 20000 MS 空间限制 : 2500 KB 对于30%的数据,有n<=1,000
对于100%的数据,有n<=1,000,000
这道题乍一看很简单,用一个数组循环遍历一遍即可,但提交过后会发现 MLE,因为 人品有问题
空间限制 : 2500 KB
根本没有数组的余地……
但是,我们如果知道丢失珠子的编号和和平方和,就可以解出他们的值!我用q_h表示和,q_ss表示平方和;
for(int i=1;i<=min(n,q_h);i++){
if(i*i+(q_h-i)*(q_h-i)==q_ss){
cout<<i<<" "<<(q_h-i)<<endl;
return 0;
}
}
所以完整代码:
#include<bits/stdc++.h>
using namespace std;
int n,n_h=0,n_ss=0,q_h=0,q_ss=0;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
n_h+=i;
n_ss+=i*i;
}
for(int i=1;i<=n-2;i++){
int b;
cin>>b;
q_h+=b;
q_ss+=b*b;
}
q_h=n_h-q_h;
q_ss=n_ss-q_ss;
for(int i=1;i<=min(n,q_h);i++){
if(i*i+(q_h-i)*(q_h-i)==q_ss){
cout<<i<<" "<<(q_h-i)<<endl;
return 0;
}
}
return 0;
}