You're given an array aa. You should repeat the following operation kk times: find the minimum non-zero element in the array, print it, and then subtract it from all the non-zero elements of the array. If all the elements are 0s, just print 0.
Input
The first line contains integers nn and kk (1≤n,k≤105)(1≤n,k≤105), the length of the array and the number of operations you should perform.
The second line contains nn space-separated integers a1,a2,…,ana1,a2,…,an (1≤ai≤109)(1≤ai≤109), the elements of the array.
Output
Print the minimum non-zero element before each operation in a new line.
Examples
input
3 5
1 2 3
output
1
1
1
0
0
input
4 2
10 3 5 3
output
3
2
Note
In the first sample:
In the first step: the array is [1,2,3][1,2,3], so the minimum non-zero element is 1.
In the second step: the array is [0,1,2][0,1,2], so the minimum non-zero element is 1.
In the third step: the array is [0,0,1][0,0,1], so the minimum non-zero element is 1.
In the fourth and fifth step: the array is [0,0,0][0,0,0], so we printed 0.
In the second sample:
In the first step: the array is [10,3,5,3][10,3,5,3], so the minimum non-zero element is 3.
In the second step: the array is [7,0,2,0][7,0,2,0], so the minimum non-zero element is 2.
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string.h>
using namespace std;
int a[100000];
int main()
{
long long int n,k;//代表n个数 输出k次
scanf("%lld%lld",&n,&k);
for(int i=0;i<n;++i)
scanf("%d",&a[i]);
sort(a,a+n);
int num;
int xx=0;
int nn=0;
for(int i=0;i<k;++i)//每次都要保证有输出的
{
if(a[i]>0)
{
num=a[i];
printf("%d\n",num);
for(int j=i;j<n;++j)
{
a[j]-=num;
}
++xx;//代表输出个数
}
else if(a[i]==0&&i<n-1)
{
k++;
nn++;
continue;
}
// else if(a[n-1]<=0)
// break;
}
for(int i=0;i<k-xx-nn;++i)
printf("0\n");
return 0;
}
上面的代码样例通过,但是在提交的时候回输出超限。
为了解决输出超限的问题,可以想办法去掉for循环里面的那个for循环。
里面的那个for循环的作用是使每一个数都减去最小的数,每计算一遍,减去一次,这样的话,时间复杂度会十分的高。
那么可以考虑,用一个数去记录要减去的数,使一次for循环,只减去一个数或者一个数都不减去。
下面的是优化后的代码:
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string.h>
using namespace std;
long long int a[100000];
int main()
{
long long int n,k;//代表n个数 输出k次
scanf("%lld%lld",&n,&k);
for(int i=0;i<n;++i)
scanf("%lld",&a[i]);
int num=0;
int xx=0;
int nn=0;
sort(a,a+n);
for(int i=0;i<n;++i)//每次都要保证有输出的
{
if(a[i]>0&&a[i]!=num)
{
printf("%d\n",a[i]-num);
num+=a[i]-num;
++xx;//代表输出个数
if(xx>k-1) break;
}
else if(a[i]==0)
{
k++;
nn++;
continue;
}
else if(a[n-1]<=0)
break;
}
for(int i=0;i<k-xx-nn;++i)
printf("0\n");
return 0;
}
减去了一个for循环,时间减少了特别多。
不过这个代码有很多地方是没有意义的,下面的修改后的代码:
#include<string.h>
#include<algorithm>
#include<math.h>
#define M(a) memset(a,0,sizeof(a))
#include<stdio.h>
using namespace std;
long int a[1010000];
int main()
{
long long int n,k;
scanf("%lld%lld",&n,&k);
for(int i=0;i<n;++i) scanf("%d",&a[i]);
sort(a,a+n);//数组从小到大排列
int ans=0;
int num=0;
for(int i=0;i<n&&ans<k;++i)
{
if(a[i]>num)
{
printf("%d\n",a[i]-num);
num+=a[i]-num;
++ans;
}
}
for(int i=0;i<k-ans;++i)
printf("0\n");
return 0;
}
本题中,n和k的大小是未知的,那么k的值就有可能是大于n的,那么在计算的时候要考虑后者大于前者的情况。
为了实现一层for循环,在计算的时候先用sort函数对输入数据的数组进行排序。(num为每个数减去的值)
然后对数组中的每一个元素进行判断,如果这个数大于0,那么就让这个数减去num然后再输出(a[i]一定会大于num)
最后会有出现0的情况,那么k减去printf的次数就是结果。