【普及组】

【P1372】又是毕业季I

这k个数就是x,x*2,...,x*k,所以符合条件的x即为答案,x*k<=n,x<=n/k,因此答案即n/k。

#include<bits/stdc++.h>
using namespace std;
int n,k;
int main(){
    scanf("%d%d",&n,&k);
    printf("%d
",n/k);
    return 0;
} 
View Code

【P1338】末日的传说

题意是求1~n的排列中字典序最小的满足m个逆序对的排列。

n个数字最多存在n*(n-1)/2对逆序对,那么考虑每个数i的位置,剩下的n-i个数最多存在逆序对对数为(n-i)(n-i-1)/2,若此对数大于等于m,则直接输出当前排序;否则把i放在排列末尾使得字典序最小,这样会产生n-i对逆序对,将m更新为m-(n-i)即可。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,m,q[50005],tmp,cnt,num;
int main(){
    cin>>n>>m;num=n;
    for(int i=1;i<=n;i++){
        tmp=(n-i)*(n-i-1)/2;
        if(tmp>=m) q[++cnt]=i;
        else q[num--]=i,m-=(n-i);
    }
    for(int i=1;i<=n;i++) cout<<q[i]<<' ';
    return 0;
}
View Code

【P1582】倒水

用二进制表示,因为所有的水都是由两份相同的水合并成的,因此每瓶水的体积一定是2的x次方升。最后保留的k个瓶子,那么最后总的二进制数中1的个数不超过k,用lowbit解决。__builtin_popcount(x)返回一个二进制数中有多少1。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,k,ans;
int main(){
    cin>>n>>k;
    while(__builtin_popcount(n)>k) ans+=n&-n,n+=n&-n;
    cout<<ans<<endl;
    return 0;
} 
View Code

 

 

原文地址:https://www.cnblogs.com/jian-song/p/11567916.html