A. Dense Array
给你一个数组,保证相邻的两数大的值不能超过小的值两倍。如果超过了,我们就必须在他们之间添加一些数保证整个序列符合上述条件,求添加的最少的数多少个。
模拟即可,如果max(a[i],a[i+1])>min(a[i],a[i+1])。那就在中间添加符合要求的即可。
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int a[55];
void solve()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
int res=0,last=a[1];
for(int i=2;i<=n;i++){
if(a[i]>last){
if(a[i]<=last*2){
last=a[i];continue;
}else{
while(a[i]>last*2){
res++;last=2*last;
}
}
}else {
if(last<=a[i]*2){
last=a[i];continue;
}
int temp=a[i];
while(temp*2<last){
res++;temp=temp*2;
}
last=a[i];
}
}
cout<<res<<'\n';
}
}
int main() {
solve();
return 0;
}
B. Balanced Remainders
给你一个数列,然后c0,c1,c2分别表示数列中n%3后的结果填充在c0,c1。c2中。然后你每次都可以对数组中的数进行+1操作,目的就是让c0=c1=c2。求最小操作次数。
模拟,首先求最终达到的平均数n/3。我们每次找(c0,c1,c2)中最大的进行操作,让它减到平均数,相应的他减少的一定会补在下一位上面(看成一个环)。最多走两遍就行。
#include <bits/stdc++.h>
#define pb push_back//vector,deque
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N=5e4+5;
int a[N];
void solve()
{
int t;
cin>>t;
while(t--){
int n,cur[3]={};
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];cur[a[i]%3]++;
}
int res=0;
while(1){
bool flag=true;
if(cur[0]!=n/3&&cur[0]>n/3){
int ad=cur[0]-n/3;
res+=ad;
cur[0]=n/3;
cur[1]+=ad;
flag=false;
}
if(cur[1]!=n/3&&cur[1]>n/3){
int ad=cur[1]-n/3;
res+=ad;
cur[1]=n/3;
cur[2]+=ad;
flag=false;
}
if(cur[2]!=n/3&&cur[2]>n/3){
int ad=cur[2]-n/3;
res+=ad;
cur[2]=n/3;
cur[0]+=ad;
flag=false;
}
if(flag)break;
}
cout<<res<<'\n';
}
}
int main() {
solve();
return 0;
}
C. Sum of Cubes
a 3 + b 3 = x a^3+b^3=x a3+b3=x给你x,问是否能找到这样的a和b(x<=1e12)
做法1:我们先枚举一个a,另外的b通过二分来求。O(n*logn,n=1e4)可做。
做法2:我们事先把(1~n)的三次方放到一个集合里,每次枚举i,寻找是否存在x-i*i*i。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5;
void solve()
{
int t;
cin>>t;
while(t--){
ll x;
cin>>x;
int flag=0;
for(int i=1;i<=10000;i++){
ll t=x-1ll*i*i*i;
ll b,l=1,r=10000;
while(l<=r){
ll mid=l+r>>1;
if(mid*mid*mid>=t){
b=mid;r=mid-1;
}else l=mid+1;
}
if(1ll*i*i*i+b*b*b==x){
cout<<"YES";flag=1;break;
}
}
if(!flag)cout<<"NO";
cout<<'\n';
}
}
int main() {
solve();
return 0;
}
D. Permutation Transformation

大佬说这是笛卡尔数,菜鸡dfs写了。模拟
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e3+5;
int a[N],ans[N];
void dfs(int l,int r,int cnt)
{
if(l>r)return ;
int pos,maxx=0;
for(int i=l;i<=r;i++){
if(a[i]>maxx){
pos=i;maxx=a[i];
}
}
ans[pos]=cnt;
dfs(l,pos-1,cnt+1);
dfs(pos+1,r,cnt+1);
}
void solve()
{
int t;
cin>>t;
while(t--){
int n,pos=-1;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];if(a[i]==n)pos=i;
}
ans[pos]=0;
dfs(0,pos-1,1);
dfs(pos+1,n-1,1);
for(int i=0;i<n;i++)cout<<ans[i]<<' ';
cout<<'\n';
}
}
int main() {
solve();
return 0;
}
E. Accidental Victory
给一个序列,每次选择两个数进行PK,大的能够获胜并吞并小的分数,数组长度-1,继续选择两个数进行PK。其中分数相同的人随机选择一个人获胜,最后求有多少个下标这样的数能赢到最后。
要想获胜分数肯定不能是最小的一开始,首先就是排序,因为排好序后,最后一个人肯定能站到最后,除此之外倒数第二个相对于前n-1也一定能占到最后,但是它拿到前n-2个人的分数后,必须保证>a[n]才能够真正的站到最后。以此类推。那我们就从后往前枚举保证sum[i]>=a[i+1]。否则i包括他之前的人都不可能占到最后。
#include <bits/stdc++.h>
#define pb push_back//vector,deque
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N=3e5+5;
struct node{
int val,sum,flag;
}a[N];
bool cmp(node a,node b)
{
return a.val<=b.val;
}
void solve()
{
int t;
cin>>t;
while(t--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i].val);
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
if(i==1)a[i].sum=a[i].val;
if(i>1)a[i].sum=a[i-1].sum+a[i].val;
}
int res=1;
if(n==1){
printf("1\n%d\n",a[1].val);
}else{
// for(int i=1;i<=n;i++)cout<<a[i].val<<' ';
// cout<<'\n';
a[n].flag=1;
for(int i=n-1;i>=1;i--){
if(a[i].sum>=a[i+1].val){
a[i].flag=1;res++;
}else if(i==1&&a[i].val==a[i+1].val)
a[i].flag=1,res++;
else break;
}
printf("%d\n",res);
for(int i=1;i<=n;i++){
if(a[i].flag==1)printf("%d ",a[i].val);
}
}
}
}
int main() {
solve();
return 0;
}
F. Equalize the Array
给你一个数列,通过删除一些数保证他们出现的次数一样多0或者c个。
先把他们各自出现的次数统计出来。例如1 3 2 1 4 2
。出现的次数2 2 1 1
。然后删除一些让他们出现次数一样。我们先把他们从大到小排个序,然后枚举每个数。对每个数来说,我们假定最终的cur=a[i]。那左边都是>=
。只需要删除多的就行l[i]-a[i]*i
。右边都是<=
那全删除即可r[i+1]
求最小值即可
#include <bits/stdc++.h>
#define pb push_back//vector,deque
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N=2e5+5;
ll l[N],r[N];
void solve()
{
int t;
cin>>t;
while(t--){
int n,x;
cin>>n;
map<int,int>mp;
for(int i=0;i<n;i++){
cin>>x;
mp[x]++;
}
vector<int>a;
for(auto it:mp){
a.pb(it.second);
}
sort(a.begin(),a.end(),greater<int>());
l[0]=r[a.size()+1]=0;
for(int i=0;i<a.size();i++)l[i+1]=a[i]+l[i];
for(int i=a.size()-1;i>=0;i--)r[i+1]=r[i+2]+a[i];
// int nn=a.size();
// for(int i=0;i<nn;i++)cout<<a[i]<<' ';
// cout<<'\n';
// for(int i=1;i<=nn;i++)cout<<l[i]<<' ';
// cout<<'\n';
// for(int i=1;i<=nn;i++)cout<<r[i]<<' ';
// cout<<'\n';
ll res=INF;
for(int i=0;i<a.size();i++){
res=min(res,l[i+1]+r[i+2]-1ll*(i+1)*a[i]);
}
cout<<res<<'\n';
}
}
int main() {
solve();
return 0;
}