Codeforces Round #540 (Div. 3)总结

A. Water Buying

题意:给q个询问,每个询问给出3个数字,n,a,b,a是买一升水的花费,b是买2升水的花费,求买n升水的最小花费。

思路:对于每个询问,我们比较2*a和b的大小,如果2*a比b小的话就一直买1升水就行了,否则若n是偶数,全买2升水,若n是奇数,先买一桶一升水的,剩下的全买两升水的,事实上题目里面没有规定a一定比b小,但数据里面似乎是这样的,更严谨的话就应该判断a是否大于b然后看是一升水的要不要买。

代码:

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=1e3+9;
//int a[maxn],b[maxn];
int main(){
    int i,j,k,n,t;
    cin>>t;
    for(i=1;i<=t;i++){
        ll n,a,b;
        cin>>n>>a>>b;
        if(a*2<=b){
            ll ans=a*n;
            cout<<ans<<endl;
        }
        else{
            ll ans=(n/2)*b+(n-n/2*2)*a;
            cout<<ans<<endl;
        }
    }
}

B. Tanya and Candies

题意:先删去序列里的一个数,然后看奇数位置的数之和是否和偶数位置的数之和相等,若相等,这个删去的数是好的,问有几个这样的good数

思路:统计每个位置偶数位置的数的前缀和,奇数位置的前缀和,很容易能够发现删去一个数之后,这个数之后的数的位置,奇变偶,偶变奇,那么此时偶数位置的数之和就等于eve[i-1]+odd[n]-odd[i],奇数位置的数之和就等于odd[i-1]+eve[n]-eve[i],我们判断他们是否相等就行了

代码:

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=2e5+9;
ll a[maxn],odd[maxn],eve[maxn];
int main(){
    int i,j,k,n;
    cin>>n;
    for(i=1;i<=n;i++){
        cin>>a[i];
        if(i%2==1){
            eve[i]=eve[i-1];
            odd[i]=odd[i-1]+a[i];
        }
        else{
            odd[i]=odd[i-1];
            eve[i]=eve[i-1]+a[i];
        }
    }
    ll ans=0;
    for(i=1;i<=n;i++){
        int ODD=0,EVE=0;
        ODD=odd[i-1]+eve[n]-eve[i];
        EVE=eve[i-1]+odd[n]-odd[i];
        if(ODD==EVE){
            ans++;
        }
    }
    cout<<ans<<endl;
}

C. Palindromic Matrix

题意:给你n*n个数,让你构造一个矩阵,这个矩阵左右对称,上下对称

思路:对于n是偶数的情况,我们能够发现每个数出现的次数必须是4的倍数才能构造这样的矩阵,我们开个map储存一下每个数出现的次数,只用处理左上角那四分之一部分,其余的对称就行了,对于这一部分的每个位置,遍历所有出现过的数,如果mp[x]>=4,把x放在这个位置,然后mp[x]-=4;然后n是奇数的情况,中间一行和中间一列的数mp[x]>=2就行了(最中间位置的数出现次数大于等于1就行),然后也是类似的解决方法。

代码:

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=1e3+9;
int a[maxn],p[maxn][maxn];
map<long long ,int>mp;
int main(){
    int i,j,k,n;
    cin>>n;
    for(i=1;i<=n*n;i++){
        cin>>a[i];
        mp[a[i]]++;
    }
    int _1cnt=0,_2cnt=0;
    for(auto it:mp){
       int x=it.second;
       if(n%2==0){
        if(x%4!=0){
            cout<<"NO"<<endl;
            return 0;
        }
       }
       else{
        if(x%4!=0){
            if(x%2==0){
                _2cnt++;
            }
            else if(x%2==1){
                _1cnt++;
            }
            if(_1cnt>1||_2cnt>(n/2)*2){
                cout<<"NO"<<endl;
                return 0;
            }
        }
       }
    }
    cout<<"YES"<<endl;
    if(n%2==0){
        for(i=1;i<=n/2;i++){
            for(j=1;j<=n/2;j++){
                for(auto it:mp){

                    int x=it.second,y=it.first;
                    if(x>=4&&x%4==0){//cout<<y<<endl;
                        p[i][j]=y;
                        mp[y]-=4;
                        break;
                    }
                }
                p[i][n-j+1]=p[i][j];
                p[n-i+1][j]=p[i][j];
                p[n-i+1][n-j+1]=p[i][j];
            }
        }
    }
    else{
        for(auto it:mp){
            int x=it.second;
            if(x%2)p[n/2+1][n/2+1]=it.first;
        }
        for(i=1;i<=n/2;i++){
            for(j=1;j<=n/2;j++){
                for(auto it:mp){
                    int x=it.second,y=it.first;
                    if(x>=4){
                        p[i][j]=y;
                        mp[y]-=4;
                        break;
                    }
                }
                p[i][n-j+1]=p[i][j];
                p[n-i+1][j]=p[i][j];
                p[n-i+1][n-j+1]=p[i][j];
            }
        }
        for(i=1;i<=n/2;i++){
            if(i==n/2+1)continue;
            for(auto it:mp){
                int x=it.second,y=it.first;
                if(x>=2){
                    p[i][n/2+1]=y;
                    mp[y]-=2;
                   // cout<<mp[y]<<"sfsaf"<<y<<endl;
                    break;
                }
            }
            p[n-i+1][n/2+1]=p[i][n/2+1];
        }
        for(j=1;j<=n/2;j++){
            if(j==n/2+1)continue;
            for(auto it:mp){
                int x=it.second,y=it.first;
                if(x>=2){
                   // cout<<123<<endl;
                    p[n/2+1][j]=y;
                    mp[y]-=2;
                    break;
                }
            }
            p[n/2+1][n-j+1]=p[n/2+1][j];
        }
    }
    for(i=1;i<=n;i++){
        for(j=1;j<=n;j++){
            cout<<p[i][j]<<' ';
        }
        cout<<endl;
    }
}

D1. Coffee and Coursework (Easy version)

题意:给你n杯咖啡和你需要完成的作业的页数m,如果一杯咖啡是一天中的第一杯,那么可以写ai页,如果是第二杯,可以写max(0,ai-1)页,第三杯可以写max(0,ai-2)页.......,问最少需要几天可以把作业写完

思路:先对咖啡从大到小排序,然后枚举天数,按题意暴力相加,看值的和是否大于等于m,如果是的话,就更新答案。

代码:

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=1e2+9;
int a[maxn];
bool cmp(int a,int b){
    return a>b;
}
int main(){
    int i,j,k,n,m;
    cin>>n>>m;
    int sum=0;
    for(i=1;i<=n;i++){
        cin>>a[i];
        sum+=a[i];
    }
    if(sum<m){
        cout<<-1<<endl;
        return 0;
    }
    else{
        int ans=inf;
        for(k=n;k>=1;k--){
            sum=0;
            sort(a+1,a+n+1,cmp);
            for(i=1;i<=k;i++){
                sum+=a[i];
            }
            for(i=k+1;i<=n;i++){
                sum+=max(0,a[i]-(i-1)/(k));
            }
            if(sum>=m){
                //cout<<sum<<"sfsf"<<k<<endl;
                ans=min(ans,k);
            }
        }
        cout<<ans<<endl;
    }
}

D2. Coffee and Coursework (Hard Version)

题意:这道题和D1的题意是一样的,就是数据范围不一样

思路:大致思路一样,不过由于数据范围增大,我们需要通过二分找完成作业的天数。

代码:

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
const int maxn=2e5+9;
ll a[maxn],n;
bool cmp(int a,int b){
    return a>b;
}
ll solve(int k){
        ll sum=0;
        for(ll i=1;i<=k;i++){
            sum+=a[i];
        }
        for(ll i=k+1;i<=n;i++){
            sum+=max((long long)0,a[i]-(i-1)/(k));
        }
        return sum;
}
int main(){
    ll i,j,k,m;
    cin>>n>>m;
    ll sum=0;
    for(i=1;i<=n;i++){
        cin>>a[i];
        sum+=a[i];
    }
    if(sum<m){
        cout<<-1<<endl;
        return 0;
    }
    else{
        ll ans=1e18;
        sort(a+1,a+n+1,cmp);
        ll l=1,r=n;
        while(l<r){
            int mid=(l+r)>>1;
            if(solve(mid)>=m){
                r=mid;
            }
            else{
                l=mid+1;
            }
        }
       // cout<<solve(4)<<"sfs"<<endl;
        cout<<r<<endl;
    }

E. Yet Another Ball Problem

题意:略

思路:构成成回文的形式就行了,最多有k*(k-1)对。

F1. Tree Cutting (Easy Version)

题意:给你一颗n个点的树,一些点是红色的,一些点是蓝色的,还要一些点是无色的,要你找出有多少条边拆去之后形成的两颗树,一颗树只存在红色点和无色点,一棵树只存在蓝色点和无色点。

思路:用dfs遍历整棵树,如果一个节点形成的子树包含所有的红色节点并且没有蓝色节点,则ans++。

代码:

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
const int maxn=3e5+9;
int a[maxn],ans=0,r_ct=0,b_ct=0,_rd[maxn],_bl[maxn];
vector<int>vec[maxn];
void dfs(int v,int pre){
    if(a[v]==1)_rd[v]++;
    if(a[v]==2)_bl[v]++;
    for(int i=0;i<vec[v].size();i++){
        int u=vec[v][i];
        if(u==pre)continue;
        dfs(u,v);
        _rd[v]+=_rd[u];
        _bl[v]+=_bl[u];
    }
    if((_rd[v]==r_ct&&_bl[v]==0)||(_bl[v]==b_ct&&_rd[v]==0))ans++;
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    int i,j,k,n;
    cin>>n;
    for(i=1;i<=n;i++){
        cin>>a[i];
        if(a[i]==1)r_ct++;
        if(a[i]==2)b_ct++;
    }
    for(i=1;i<n;i++){
        int x,y;
        cin>>x>>y;
        vec[x].push_back(y);
        vec[y].push_back(x);
    }
    dfs(1,0);
    cout<<ans<<endl;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值