B. Ehab and subtraction
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
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
Copy
3 5 1 2 3
output
Copy
1 1 1 0 0
input
Copy
4 2 10 3 5 3
output
Copy
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.
题意:
n个数,m次询问,m-1次操作,操作:全体减去最小非零数,初始+每次(m-1次)操作后都要输出最小非零数,如果全是0,输出0即可
分析:
其实这题很简单,比赛时候推出了一个规律,把这题弄复杂了
先说一下规律:
5 5
b[i]为排序好的数: 1 2 3 4 5
a[i]为排序好的数:1 2 3 4 5
第一次操作: b[1]-a[1] b[2]-a[1] b[3]-a[1] b[4]-a[1] b[5]-a[1]
第二次操作: b[2]-a[2] b[3]-a[2] b[4]-a[2] b[5]-a[2]
第三次操作:.。。。。。
其实就是第m次操作,b[1...i]对应的减第m个小的数
答案就是,一次for循环遍历找到b[j]-第m小的数>0输出就行。
然后,上述有两个地方要注意:
1.初始就要输出,找到非0数的位置
2.a[i]里面不该有重复的数,需要去重
#include<cstdio>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<functional>
#include<cstring>
#include<string>
#include<cstdlib>
#include<iomanip>
#include<numeric>
#include<cctype>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<list>
#include<set>
#include<map>
using namespace std;
#define N 100000+5
#define rep(i,n) for(int i=0;i<n;i++)
#define sd(n) scanf("%d",&n)
#define sll(n) scanf("%lld",&n)
#define pd(n) scanf("%d\n",n)
#define pll(n) scanf("%lld\n",n)
#define MAX 26
typedef long long ll;
const ll mod=1e9+7;
ll n,m;
ll a[N];
ll b[N];
int main()
{
//string s;
//cin>>s;
ll ans=0;
//ll sum=0;
ll x,y,d;
scanf("%lld %lld",&n,&m);
int flag=0;
for(int i=0;i<n;i++)
{
scanf("%lld",&a[i]);
}
sort(a,a+n);
for(int i=0;i<n;i++)
b[i]=a[i];
unique(a,a+n); //去重
int num=0,pos=0;
for(int i=0;i<n;i++)
{
if(a[i]>0)
{
printf("%lld\n",a[i]);
pos=i;
num++;
if(num>=m) break;
break;
}
}
if(num>=m) return 0;
for(int j=0;j<n&&pos+num-1<n;j++)
{
if(b[j]-a[pos+num-1]>0)
{
b[j]=b[j]-a[pos+num-1];
printf("%lld\n",b[j]);
num++;
if(num>=m) break;
}//cout<<" "<<num<<endl;
}
if(num<m)
{
for(int i=num+1;i<=m;i++)
printf("0\n");
}
/*for(int i=0;i<n;i++)
{
scanf("%lld%lld",&a[i],&b[i]);
} */
//for(int i=1;i<=n;i++)
// printf("%lld",a[i]);
return 0;
}
当然还有简便方法,徐大佬的优先队列
#include<iostream>
#include<cstring>
#include<queue>
#include<cstring>
using namespace std;
priority_queue<int,vector<int>,greater<int> >q;//从大到小的定义方式
int main()
{
int n,m;
int sum=0,cnt=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
q.push(x);
}
while(cnt<m)
{
if(q.empty())
{
cout<<"0"<<endl;
cnt++;
}
else
{
int k=q.top()-sum;
if(k>0)
{
cout<<k<<endl;
cnt++;
sum+=k;
q.pop();
}
else
q.pop();
}
}
return 0;
}