• Educational Codeforces Round 138 (Rated for Div. 2)


    A:思维

    题意:给一定的N*N的板子,里面放有一些乌鸦,这些乌鸦会攻击自己的所在行与所在列,问给定一个数量的乌鸦,问是否能够移动某只乌鸦,使得形成和平局面?

    方法:我们发现,N*N的板子,因为乌鸦会攻击所在行与所在列,所以要形成和平局面,则最多只能放N只乌鸦,如果多余了N只,那么肯定不会形成和平局面。所以,这题只跟板子的大小和乌鸦的数量有关。

    代码: 

    1. #include
    2. #define int long long
    3. using namespace std;
    4. const int N=1e6+10;
    5. inline void solve(){
    6. int n,m;cin>>n>>m;
    7. for(int i=1;i<=m;i++){
    8. int x,y;cin>>x>>y;
    9. }
    10. if(m"YES\n";
    11. else cout<<"NO\n";
    12. }
    13. signed main(){
    14. int T;cin>>T;
    15. while(T--) solve();
    16. }

    B:贪心

     题意:给定N个具有一定顺序排列的怪物,这个怪物本身有血量,还有一个技能,就是在这个怪物死后,发动这个技能会使他左右两边的怪物加上一定的血量。定义怪物的血量为HP的话,那么杀死这个怪物所用的时间就需要HP秒,这一个怪物死后,就消失了。他左右的邻居就相邻了。

     问如何一个一个的杀完所有的怪物使得用的时间最短?

    方法:因为杀死一个怪物,它的左右邻居都会加上一定血量,那么要想所有怪物的血量加的最少,则应该从第一个或者最后一个怪物开始杀起,因为他们的邻居只有1个,这样尽可能少的给怪物加血量。我们知道,杀完所有怪物(若所有怪物的加血技能都加0滴血),那么所需要的时间,就是所有怪物的血量和:SUM。若所有怪物的加血技能都加不为0的血量时,则所需要的最少时间一定是SUM+(N-1)个怪物的加血量。因为最后一个怪物死后,它的加血技能没有用,所以我们最优的方案一定是将加血量最多的怪物放在最后一个消灭。

    代码:

    1. #include
    2. #define int long long
    3. using namespace std;
    4. const int N=1e6+10;
    5. inline void solve(){
    6. int res=0,maxx=0;
    7. int n;cin>>n;
    8. for(int i=1;i<=n;i++){
    9. int x;cin>>x;
    10. res+=x;
    11. }
    12. for(int i=1;i<=n;i++){
    13. int x;cin>>x;
    14. res+=x;
    15. maxx=max(maxx,x);
    16. }
    17. cout<"\n";
    18. }
    19. signed main(){
    20. int T;cin>>T;
    21. while(T--) solve();
    22. }

    C:暴力+贪心 or(二分+贪心)

    题意:有n个数,Alice和Bob玩游戏。游戏进行k轮,每一轮Alice必须消除一个小于等于 k−i+1 的数,在消除之后,如果数组还有元素的话Bob需要对一个数增加 k−i+1 ,求Alice在保证自己在k轮内都能消除数的前提下,最多进行的轮次。

    分析:Alice每消除一个数,Bob就会在剩余数组中选择一个数加k-i+1。随着轮次的增加,Alice消除的数是越来越小的。这里考虑一下贪心策略。

    设想如果Bob选择的是数组中最大的数,那么Alice就肯定不会消除完所有的数,那么要想使得轮次更多,Bob选择数组中最小的数进行操作即可。

    这里解释一下Bob的选择操作:为什么每次选最小数会使轮次增加?

    选择最大的数进行操作是肯定不行的,那么选择次大数呢?这里不妨反演一遍,如果Bob每次都操作最小的数,那么最小数每次都在增大,则就一定会使轮次增大。

    代码:

    1. #include
    2. #define int long long
    3. using namespace std;
    4. int n,a[101];
    5. inline bool pd(int k){
    6. int l=1,r=n;
    7. for(int i=1;i<=k;i++){
    8. while(a[r]>k-i+1) r--;
    9. //如果一开始就是小于最大值的话,我们就减减,为的是让这个k不满足pd
    10. if(l>r) return false;//说明Bob的操作次数比Alice多,则就不可能满足pd
    11. l++,r--;//Alice从右往左操作,Bob从左往右操作
    12. }
    13. return true;
    14. }
    15. inline void solve(){
    16. cin>>n;
    17. for(int i=1;i<=n;i++) cin>>a[i];
    18. sort(a+1,a+1+n);
    19. int ans=0;
    20. for(int i=1;i<=n;i++){//为什么要在1-n范围找呢?因为k-i+1的最小值只能为1而不能为0
    21. if(pd(i)) ans=i;
    22. }
    23. cout<"\n";
    24. }
    25. signed main(){
    26. int T;cin>>T;
    27. while(T--) solve();
    28. }

  • 相关阅读:
    libstdc++.so.6: cannot open shared object file: No such file or directory
    100天掌握网络安全知识点!
    如何选择合适的HTTP代理服务器
    面试题-React(九):React的Context:实现非父子组件通信
    基于R语言机器学习方法与案例分析实践技术
    SOC-hello world
    一幅长文细学算法(一)——C++STL
    【PyGIS】ERA5降雨蒸散发数据预处理
    AI计算机视觉进阶项目(一)——带口罩识别检测(3)
    轻松实现PDF文件的在线浏览
  • 原文地址:https://blog.csdn.net/YuDuna/article/details/127441629