A
模拟即可
B
给你 n n n个数字,然后让你找尽可能多的数,使得这些数的平均值大于等于 x x x。
思路:
当然尽可能的选择大的数字来平均,所以从大到小排个序,然后不断取数看是否成立。
ll a[N];
int main(){
int t = read();
while(t--){
int n = read(),x = read();
rep(i,1,n) a[i] = read();
sort(a+1,a+n+1,greater<ll>());
ll sum = 0;
int ans = n;
rep(i,1,n){
sum += a[i];
if(sum<1LL*x*i) {ans = i-1;break;}
}
cout<<ans<<endl;
}
}
C
有一个 n n n个怪物构成的环,每个怪物的血量为 a i a_i ai,死亡爆炸后对下一个怪物造成的伤害为 b i b_i bi,一颗子弹造成一滴血的伤害,现在问最少花费多少子弹可以消灭全部的怪物。
思路:
妈耶,我一直往排序上死劲了。。。
打爆一个关怪物会造成爆炸,对下一个怪物造成伤害,做法是枚举消灭的第一个怪物。破环为链,借助前缀和枚举花费最小值。因为如果在攻击别的怪物的话,会多余的浪费子弹,本来上一个怪物可以对这个怪物造成爆炸伤害的。
注意最大值的选取尽可能的大。
ll a[N],b[N];
ll c[N];
ll sum[N];
int main(){
int t = read();
while(t--){
int n = read();
rep(i,1,n){
a[i] = read(),b[i] = read();
b[i+n] = b[i];
c[i] = c[i+n] = a[i+n] = a[i];
}
c[1] -= b[2*n];
rep(i,2,2*n){
c[i] -= b[i-1];
if(c[i]<0) c[i] = 0;
}
rep(i,1,2*n) sum[i] = sum[i-1] + c[i];
ll M = 1e18;
rep(i,1,n){
M = min(M,a[i]+sum[i+n-1]-sum[i]);
}
cout <<M<<endl;
}
}
D
题意:
给你一个有向完全图,然后让你输出字典序最小的一个欧拉回路的 [ l , r ] [l,r] [l,r]段。
思路:
比如 n = 4 n=4 n=4
答案就是 [ 1 , 2 , 1 , 3 , 1 , 4 , ( 2 , 3 , 2 , 4 , ( 3 , 4 , ( 1 ] [1,2,1,3,1,4,(2,3,2,4,(3,4,(1] [1,2,1,3,1,4,(2,3,2,4,(3,4,(1]
思路:
因为 [ l , r ] [l,r] [l,r]区间范围 1 e 5 1e5 1e5级别。所以二分查找每一个数即可。
ll Find(ll x,ll n){
ll l = 0,r = n;
while(l < r){
ll mid = l + r + 1>>1;
ll va = 2LL*(n-1)*mid - mid*(mid-1);
if(va < x) l = mid;
else r = mid - 1;
}
ll va = 2LL*(n-1)*l - l*(l-1);
x -= va;
if(x & 1) return l + 1;
else return (x/2) + l + 1;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int t = read();
while(t--){
ll n = read(), l = read(), r= read();
ll p = n*n - n +1;
for(ll i = l;i <= r;++i){
// bug;
if(i == p) cout<<1<<' ';
else {
cout << Find(i,n)<<' ';
}
}
puts("");
}
return 0;
}