Codeforces Round #835 (Div. 4)
C. Advantage
题意:找每个数和最大数的差或者次大数的差。
分析:维护一下最大值和次大值 //因为1e5,不能嵌套循环,最多nlogn
1 #include <bits/stdc++.h> 2 #define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) 3 const int N=2e5+10; 4 int a[N];int n; 5 6 using namespace std; 7 void solve() 8 { 9 cin>>n; 10 vector<int>res; 11 for(int i=1;i<=n;i++)cin>>a[i],res.push_back(a[i]); 12 sort(res.begin(),res.end()); 13 for(int i=1;i<=n;i++) 14 { 15 if(a[i]!=res.back()) cout<<a[i]-res.back()<<' '; 16 else cout<<a[i]-res[res.size()-2]<<' '; 17 } 18 cout<<endl; 19 } 20 signed main() 21 { 22 io; 23 int T=1; 24 cin>>T; 25 while(T--)solve(); 26 }
D.Challenging Valleys
就是需要你求出 \__/ 形状的数量, 然后可以发现, 中间的 __ 可以压缩成一个点, 我们就是要求 \/ 的数量, 也就是山谷的数量, 将原数组压缩后, 统计山谷数量即可, 判断是否为 1
1 #include <bits/stdc++.h> 2 #define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) 3 using namespace std; 4 const int N=2e5+10; 5 int n,a[N]; 6 void solve() 7 { 8 cin>>n; 9 vector<int>res; 10 for(int i=1;i<=n;i++)cin>>a[i]; 11 res.push_back(a[1]); 12 for(int i=2;i<=n;i++)if(a[i]!=a[i-1])res.push_back(a[i]); 13 int ans=0; 14 for(int i=0;i<res.size();i++) 15 { 16 if((i==0||res[i]<res[i-1])&&(i==res.size()-1 || res[i]<res[i+1]))ans++; 17 } 18 if(ans==1)cout<<"YES"<<endl; 19 else cout<<"NO"<<endl; 20 } 21 signed main() 22 { 23 io; 24 int t=1; 25 cin>>t; 26 while(t--)solve(); 27 }
E. Binary Inversions
题意:有一组01序列,可以换其中的一个数(0->1/1->0)或不换,使逆序对最多并输出数量
ans1 不换 : 直接求逆序对
ans2 换最前面的0->1
ans3 换最后边的1->0
然后输出max{ans1,ans2,ans3}
0变1 加上后面的0减去前面的1
1变0 减去后面的0加上前面的1
//还是1e5数据,不能开二次循环,这题快排求逆序对也卡了,还是线性O(n)吧
1 #include <bits/stdc++.h> 2 #define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) 3 using namespace std; 4 const int N=2e5+10; 5 int a[N],b[N]; 6 inline void solve() 7 { 8 int n;cin>>n; 9 for(int i=1;i<=n;i++) 10 { 11 cin>>a[i]; 12 b[i]=a[i]; 13 } 14 //求原逆序对 15 int res1=0; 16 int cnt=0; 17 for(int i=n;i>=1;i--) 18 { 19 if(a[i]==0)cnt++; 20 else 21 { 22 res1+=cnt; 23 } 24 } 25 //求最后面的1换成0的逆序对 26 int res2=0; 27 cnt=0; 28 for(int i=n;i>=1;i--) 29 { 30 if(a[i]==1) 31 { 32 a[i]=0;break; 33 } 34 } 35 for(int i=n;i>=1;i--) 36 { 37 if(a[i]==0)cnt++; 38 else 39 { 40 res2+=cnt; 41 } 42 } 43 //求最前面0换成1的逆序对 44 int res3=0; 45 cnt=0; 46 for(int i=1;i<=n;i++) 47 { 48 if(b[i]==0) 49 { 50 b[i]=1;break; 51 } 52 } 53 for(int i=n;i>=1;i--) 54 { 55 if(b[i]==0)cnt++; 56 else res3+=cnt; 57 } 58 int ans=max(res1,res2); 59 ans=max(ans,res3); 60 cout<<ans<<endl; 61 } 62 int main() 63 { 64 io; 65 int t=1; 66 cin>>t; 67 while(t--)solve(); 68 return 0; 69 }
F.Quests 二分
题意:d天凑够c,k是使用完ai多少天不能再用ai的CD,求最大k
分析:若max{a最大}*d<c 说明无解,若reverse sort(ai)的前缀和S,S(min(n,d))>=c,就说明k无论多大都有解,
剩下的就二分(0,d)区间,每次加最大的前mid+1(此时mid+1即为单位周期)个数,若不够就从最大值开始加到d个为止
//注意!!此时需要开long long!!会爆int
1 #include <bits/stdc++.h> 2 #define io ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) 3 #define int long long //开longlong!!! 4 using namespace std; 5 const int N=2e5+10; 6 int a[N],s[N]; 7 int n,c,d; 8 bool check(int mid) 9 { 10 int sum=0,cnt=0;//cnt代表天数(轮数,极限是d) 11 for(int i=1;i<=mid+1;i++) 12 { 13 sum+=a[i]; 14 cnt++; 15 if(cnt==d)break; 16 if(i==mid+1)i=0;//因为一天最多做一件,所以在最大天没完时候让其死循环求出最大天做多少 17 } 18 if(sum>=c)return true; 19 return false; 20 } 21 inline void solve() 22 { 23 cin>>n>>c>>d; 24 for(int i=1;i<=d;i++)a[i]=0; 25 for(int i=1;i<=n;i++)cin>>a[i]; 26 27 sort(a+1,a+1+n,greater<int>()); 28 for(int i=1;i<=n;i++)s[i]=s[i-1]+a[i]; 29 30 if(s[min(d,n)]>=c){cout<<"Infinity"<<endl;return;} 31 if(a[1]*d<c){cout<<"Impossible"<<endl;return;} 32 int l=0,r=d; 33 while(l<r) 34 { 35 int mid=l+r+1>>1; 36 if(check(mid))l=mid; 37 else r=mid-1; 38 } 39 cout<<l<<endl; 40 } 41 signed main() 42 { 43 io; 44 int t; 45 cin>>t; 46 while(t--)solve(); 47 return 0; 48 } 49
本文作者:Zac-saodiseng
本文链接:https://www.cnblogs.com/Zac-saodiseng/p/16922962.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步