文章目录
D. Permutation Transformation
题目分析:
dfs逐步找根
AC代码:
#include<bits/stdc++.h>
using namespace std;
int a[109];
int d[109];
void build(int l,int r,int k){
if(l>=r){
return ;
}
int mx=a[l],cmx=l;
for(int i=l+1;i<r;i++){
if(a[i]>mx){
mx=a[i];
cmx=i;
}
}
d[cmx]=k;
build(l,cmx,k+1);
build(cmx+1,r,k+1);
}
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
int k=0,l=0,r=n;
build(l,r,k);
for(int i=0;i<n;i++){
cout<<d[i]<<" ";
}
cout<<endl;
}
return 0;
}
F. Equalize the Array
题目分析:
题目要求是,删除最小的个数,使剩下每个数字的个数一样;
删除最少的,不就是剩下的最多吗?把个数排序,然后判断,假使剩下的数字都为某个数,那么还剩下多少数,找到最大的这个值。结果就是n-这个值。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e9+9;
int main(){
int t;
cin>>t;
while(t--){
map<int,int>mpp;
vector<int>b;
b.clear();
int n;
cin>>n;
int mx=0;
for(int i=0;i<n;i++){
int x;
cin>>x;
mpp[x]++;
}
map<int,int>::iterator it=mpp.begin();
for(;it!=mpp.end();it++){
b.push_back(it->second);
}
sort(b.begin(),b.end());
int ans=0,tmp=0;
for(int i=0;i<b.size();i++){
tmp=b[i]*(b.size()-i);
ans=max(ans,tmp);
}
cout<<n-ans<<endl;
}
return 0;
}
E. Accidental Victory
题目入口
题目分析:
题目要求是,找到有可能赢的全部选手;
所有数排序后,如果前一个数的前缀和大于等于后一个数,那么他有赢的希望(需要注意的是,如果这个人要赢,他的后一个也会有可能赢:比如 1 2 3 9 11 13,2有赢的希望,但是2最终不可能赢,因为1+2+3=6<9)(所以此题可以从后往前)
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
const int maxn=2*1e5+9;
typedef struct{
int a;
int cur;
ll sum;
}ap;
ap arr[maxn];
bool cmp(ap x,ap y){
return x.a<y.a;
}
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
arr[0].a=arr[0].sum=0;
for(int i=1;i<=n;i++){
cin>>arr[i].a;
arr[i].cur=i;
}
sort(arr+1,arr+1+n,cmp);//先排序
for(int i=1;i<=n;i++){
arr[i].sum=arr[i-1].sum+arr[i].a;//pre sum
}
vector<int>res;
res.clear();
res.push_back(arr[n].cur);//最大的也是会赢的
for(int i=n-1;i>=1;i--){
if(arr[i].sum>=arr[i+1].a){
res.push_back(arr[i].cur);
}
else{
break;
}
}
// for(int i=1;i<n;i++){
// if(arr[i].sum>=arr[i+1].a){
// res.push_back(arr[i].cur);
// }
//
// }//这是错误的,只比后一个大最后不一定赢
cout<<res.size()<<endl;
sort(res.begin(),res.end());
for(int i=0;i<res.size();i++){
cout<<res[i]<<" ";
}
cout<<endl;
}
return 0;
}
C. Sum of Cubes
题目入口
题目分析:
这个题我看到是没思路的。。。
原来“暴力”是这样的“ brute force”,原来map的预处理可以如此牛,原来map<ll,ll>和map<ll,int>即使数据满足范围,值可能不一样。。
参考的CSDN博文:
x最大为1e12,所以只需要预处理1~1e4的立方,存储即可;
然后判断map[x-iii]是否为1.。。
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
map<ll,ll>mpp;
int main(){
for(ll i=1;i<=1e4;i++){
mpp[i*i*i]=1;
}
int t;
cin>>t;
while(t--){
ll x;
cin>>x;
bool f=false;
for(ll i=1;i<=1e4;i++){
ll b=x-i*i*i;
if(mpp.find(b)!=mpp.end()&&mpp[b]){
f=true;
break;
}
}
if(f){
cout<<"YES"<<endl;
}else{
cout<<"NO"<<endl;
}
}
return 0;
}
B. Balanced Remainders
题目入口
问题分析:
题目要求是数字mod3后为0,1,2的数字个数相同;
看代码。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int a[3]={0};
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i=0;i<n;i++){
int x;
cin>>x;
a[x%3]++;
}
int ans=0;
int t=(a[0]+a[1]+a[2])/3;
while(!(a[0]==a[1]&&a[1]==a[2])){
while(a[0]<t){
a[0]++;
a[2]--;
ans++;
}
while(a[1]<t){
a[1]++;
a[0]--;
ans++;
}
while(a[2]<t){
a[2]++;
a[1]--;
ans++;
}
}
cout<<ans<<endl;
}
return 0;
}