• Codeforces Round #835 (Div. 4)


    比赛链接:Dashboard - Codeforces Round #835 (Div. 4) - Codeforces

    A: 排序

    题意:给定三个数,求第二大数

    思路:排一遍序,输出第二个数即可

    代码:

    1. #include
    2. #define int long long
    3. #define fast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    4. using namespace std;
    5. const int N=2e5+10;
    6. int a[N];
    7. inline void solve(){
    8. for(int i=1;i<=3;i++) cin>>a[i];
    9. sort(a+1,a+1+3);
    10. cout<2]<<"\n";
    11. }
    12. signed main(){
    13. fast;
    14. int T;cin>>T;
    15. while(T--) solve();
    16. }

    B: 排序

     题意:找最大字符

    思路:排序即可

    代码:

    1. #include
    2. #define int long long
    3. #define fast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    4. using namespace std;
    5. const int N=2e5+10;
    6. int a[N];
    7. inline void solve(){
    8. int n;string s;cin>>n>>s;
    9. sort(s.begin(),s.end());
    10. char aa=s[s.size()-1];
    11. int ans=aa-'a'+1;
    12. cout<"\n";
    13. }
    14. signed main(){
    15. fast;
    16. int T;cin>>T;
    17. while(T--) solve();
    18. }

    C:贪心

    题意:给定长度为N的数组,找每个数与最大数的差值,如果本身就是最大数,则差值为最大数-次大数 

    思路:排一次序。依次运算即可

    代码:

    1. #include
    2. #define int long long
    3. #define fast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    4. using namespace std;
    5. const int N=2e5+10;
    6. int a[N],b[N];
    7. inline void solve(){
    8. int n;cin>>n;
    9. for(int i=1;i<=n;i++) cin>>a[i],b[i]=a[i];
    10. sort(b+1,b+1+n);
    11. if(b[1]==b[n]){
    12. for(int i=1;i<=n;i++) cout<<"0 ";
    13. cout<<"\n";return;
    14. }
    15. for(int i=1;i<=n;i++){
    16. if(a[i]==b[n]) cout<<(a[i]-b[n-1])<<" ";
    17. else cout<<(a[i]-b[n])<<" ";
    18. }
    19. cout<<"\n";
    20. }
    21. signed main(){
    22. fast;
    23. int T;cin>>T;
    24. while(T--) solve();
    25. }

    D:思维+模拟

     这里直接说结论吧

    结论:找到山谷后,后面的上升序列只能一直升,不能降

    代码:

    1. #include
    2. #define int long long
    3. #define fast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    4. using namespace std;
    5. const int N=2e5+10;
    6. int a[N],d[N];
    7. inline void solve(){
    8. int n;cin>>n;
    9. for(int i=1;i<=n;i++) cin>>a[i];
    10. bool ok=false;//表示是否为升序
    11. for(int i=2;i<=n;i++){
    12. if(a[i]==a[i-1]) continue;
    13. if(ok){
    14. if(a[i]-1]){
    15. cout<<"NO\n";return;
    16. }
    17. }
    18. if(a[i]>a[i-1]) ok=true;
    19. }
    20. cout<<"YES\n";
    21. }
    22. signed main(){
    23. fast;
    24. int T;cin>>T;
    25. while(T--) solve();
    26. }

     E:前后缀

     题意:给定 01 串,求最多反转其中一个位置的前提下,最大的逆序对数

    吐槽:一开始考虑贪心,直接搞TLE了。然后又O(N^2)求逆序对,也炸了。没有脑子捏。。。

    思路:这里用前后缀进行优化

    先算出初始的逆序对数量,接下来考虑每个点翻转对答案的影响。

    如果是 0 变成 1 ,那么对答案的影响是减去后面的 1 的数量,加上前面 0 的数量。

    如果是 1 变成 0 ,那么对答案的影响是减去后面 0 的数量,加上前面 1 的数量。

    用前后缀分别维护出一个位置前面和后面 1 和 0 的数量即可。

    代码:

    1. #include
    2. #define int long long
    3. #define fast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    4. using namespace std;
    5. const int N=2e5+10;
    6. int arr[N],p1[N],s1[N],p0[N],s0[N];
    7. //p1:表示当前位置前面有多少个1
    8. //p0:表示当前位置前面有多少个0
    9. //s1:表示当前位置后面有多少个1
    10. //s0:表示当前位置后面有多少个0
    11. inline void solve(){
    12. int n;cin>>n;int sum=0;//sum记录逆序对数
    13. for(int i=1;i<=n;i++) cin>>arr[i];
    14. int a=0,b=0;//a表示1的个数,b表示0的个数
    15. for(int i=n;i>=1;i--){
    16. if(arr[i]==1){
    17. s1[i]=a;s0[i]=b;
    18. a++;sum+=b;
    19. }
    20. else{
    21. s1[i]=a;s0[i]=b;b++;
    22. }
    23. }
    24. a=0,b=0;
    25. for(int i=1;i<=n;i++){
    26. if(arr[i]==1){
    27. p1[i]=a;p0[i]=b;a++;
    28. }
    29. else{
    30. p1[i]=a;p0[i]=b;b++;
    31. }
    32. }
    33. int ans=sum;
    34. for(int i=1;i<=n;i++){//进行枚举判断
    35. if(arr[i]) ans=max(ans,sum+p1[i]-s0[i]);
    36. else ans=max(ans,sum-p1[i]+s0[i]);
    37. }
    38. //ps:p0和s1数组没有用到捏...q.q
    39. cout<"\n";
    40. }
    41. signed main(){
    42. int T;cin>>T;
    43. while(T--) solve();
    44. }

     F:二分+贪心

    题意:有 n 个任务,每个任务做完会获得 ai 的奖励,任务做完会有 x 天的 cd ,必须在 x+1 天才能继续完成这个任务。给定参数 c,d ,请问在 d 天获得至少 c 的奖励的最大cd是多少。

    思路:先考虑特判,先从大到小sort一遍。

    如果不存在冷却时间的情况下,如果每天都选择最大的得分(maxx),d*maxx

    再考虑无穷解的情况:同样如果不存在冷却时间的情况下,每天都选择一个数,sum记录和,如果sum>=c,则是无穷解。为什么?

    因为,如果前面有一个大于c的,就可以是无穷解,或者是2个的和>c,或者是d个的和>c

    然后就是考虑一半情况:这里选择二分答案

    1. #include
    2. #define int long long
    3. #define fast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    4. using namespace std;
    5. const int N=2e5+10;
    6. int a[N],n,c,d;
    7. bool check(int mid){
    8. int sum=0;
    9. for(int i=1;i<=min(mid+1,n);i++){
    10. for(int j=i;j<=d;j+=mid+1){
    11. sum+=a[i];
    12. if(sum>=c) return true;
    13. }
    14. }
    15. return false;
    16. }
    17. inline void solve(){
    18. cin>>n>>c>>d;
    19. int maxx=0,sum=0;
    20. for(int i=1;i<=n;i++){
    21. cin>>a[i];maxx=max(maxx,a[i]);
    22. }
    23. sort(a+1,a+1+n,greater<int>());
    24. for(int i=1;i<=min(d,n);i++) sum+=a[i];
    25. if(d*maxx"Impossible\n";
    26. else{
    27. if(sum>=c){
    28. cout<<"Infinity\n";return;
    29. }
    30. int L=0,R=2e5;
    31. while(L+1
    32. int mid=L+R>>1;
    33. if(check(mid)) L=mid;
    34. else R=mid;
    35. }
    36. cout<"\n";
    37. }
    38. }
    39. signed main(){
    40. int T;cin>>T;
    41. while(T--) solve();
    42. }

    G:DFS

    题意: 给定一棵带边权的树,给定起点 a 和终点 b ,从 a 出发,刚开始的分数为 0 ,每走过一条边会使分数异或上这个值,要求最后走到 b 的分数为 0 ,并可以进行任意一次传送,求能否满足要求

    思路:转化一下观点。从a到b,使得最终到达b时,xor为0。双向DFS一下。从a跑一遍,从b跑一遍。比如从a跑到点x的值为m,从b跑到点y的值为n,那么我们一定可以知道m==n

    为什么?

    因为题目中说了,可以传送一次点位,那么x点就可以直接传到y点,这样路径就连接起来了。

    如果有交点怎么办?

    其实交点就可以直接忽略掉,因为是xor,所以两条路径都有这个点,那么就xor为0了,可以直接消除。

    所以最终做法:我们先搜一遍a,把xor值放入set中,再搜一遍b,判断xor值是否在set中出现即可

    代码:

    1. #include
    2. #define int long long
    3. #define fast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    4. using namespace std;
    5. const int N=2e5+10;
    6. typedef pair<int,int>PII;
    7. int n,a,b;
    8. vectorve[N];
    9. set<int>se;
    10. bool ok;
    11. void dfs1(int u, int fa, int sum){
    12. se.insert(sum);
    13. for(auto [x, y] : ve[u]){
    14. if(x == fa) continue;
    15. if(x != b)
    16. dfs1(x, u, sum ^ y);
    17. }
    18. }
    19. void dfs2(int u, int fa, int sum){
    20. for(auto [x, y] : ve[u]){
    21. if(x == fa) continue;
    22. if(se.count(sum ^ y)) ok = 1;
    23. dfs2(x, u, sum ^ y);
    24. }
    25. }
    26. void solve(){
    27. cin >> n >> a >> b;
    28. ok = false;se.clear();
    29. for(int i = 1; i <= n; i ++ ) ve[i].clear();
    30. for(int i = 1; i <= n - 1; i ++ ){
    31. int x, y, z;cin >> x >> y >> z;
    32. ve[x].push_back({y, z});
    33. ve[y].push_back({x, z});
    34. }
    35. dfs1(a, 0, 0);dfs2(b, 0, 0);
    36. if(ok) cout << "YES\n";
    37. else cout << "NO\n";
    38. }
    39. signed main(){
    40. int T;cin>>T;
    41. while(T--) solve();
    42. }

  • 相关阅读:
    java计算机毕业设计天津城建大学校友录管理系统源程序+mysql+系统+lw文档+远程调试
    【软件工程_软件工程项目管理】课后题
    Java6种单例模式写法
    Java手写动态连通性问题算法和动态连通性问题算法应用拓展案例
    Go笔记20221124
    jsp中使用PDF.js实现pdf文件的预览
    Spring Framework IoC依赖注入-按Bean类型注入
    一种多引擎可视化数据流实现方案
    jenkins安装-linux
    【MySQL视图】视图的概念、创建、查看、删除和修改
  • 原文地址:https://blog.csdn.net/YuDuna/article/details/127990805