首页 > 其他分享 >Codeforces Round 893 (Div. 2) A-C题解

Codeforces Round 893 (Div. 2) A-C题解

时间:2023-08-21 17:23:17浏览次数:39  
标签:893 饼干 小贩 int 题解 pos vec Div dis

CF 893 (Div.2)

A. Buttons

签到题。两人会优先选择c中的按钮来,避免自己的按钮消耗同时减少对方可选择的按钮。所以c % 2 == 1等价于a的按钮数+1,c % 2 == 0时相当于c按钮不存在,比较a b 按钮的数量来得出答案即可。

#include<iostream>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
const int INF = 2e9;



void solve() {
    int a, b, c;
    cin >> a >> b >> c;
    if(c % 2 == 1){
        a++;
    }
    if(a > b){
        cout << "First" << endl;
    }
    else{
        cout << "Second" << endl;
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        solve();
    }

    return 0;
}

 

B. The Walkway

有n个位置,有m个小贩,m <= n。每个小贩都有一个位置(1 <= pos <= n),任意两个小贩的位置不重合。Petya从1走到n,当满足以下条件时,他会在某个点吃饼干

  • 如果这个点是一号点,他会吃一次饼干

  • 否则,如果这个点上有小贩,他会吃一次饼干

  • 否则,如果这个点和上个吃饼干的点之间的距离为d,他会吃一次饼干

现在给出n, m, d,2 <= d <= n <= 1e9, 2 <= m <= min(1e5, n), 问如果可以并且必须移除一个小贩,那么Petya能吃到的最少的饼干数量是多少,并且有多少种移除小贩的方案。

 

首先会发现,任意两个小贩之间(把1号点,因为此时强制吃饼干,也视为一个小贩),那么从上一个小贩处(已经吃了饼干)到这个小贩处(此时需要吃饼干)吃掉饼干的数量为

 int cnt = (pos - pre) + 1;
 if((pos - pre) % d == 0){
  cnt--;
 }

我们可以记录下到每一个小贩时会再吃多少个饼干。

如果此时前面的小贩数量足够多(指到此时为止小贩的数量大于等于三),那么可以考虑移除前一个小贩会产生的变化:从上上个小贩处到此处新的消耗饼干的数量

 int dis = (vec[vec.size() - 1 - 1 - 1].first) - pos; //vec[i].fist -> 第i个小贩的位置, second -> 上述定义的饼干消耗
 int ncnt = (dis / d) + 1;
 if(dis % d == 0){
  cnt--;
 }

计算一下新的消耗比改变前的消耗少多少,对m个小贩不断更新即可。

最终退出循环时再相似的方法判断一下移除最后一个小贩的影响。

以及特判一下在第一个位置是否有小贩,以及此时饼干消耗的最大改变量是不是0即可。

#include<iostream>
#include<vector>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
const int INF = 2e9;



void solve() {
    int n, m, d;
    cin >> n >> m >> d;
    vector<pii> vec;
    int pre = 1;
    vec.push_back({1, 1});
    int maxminus = 0;
    int num = 0;
    vector<int> b;
    for(int i = 0; i < m; i++){
        int pos;
        cin >> pos;
        b.push_back(pos);
        if(pos == 1){
            continue;
        }
        int cnt = (pos - pre) / d + 1;
        if((pos - pre) % d == 0){
            cnt--;
        }
        //cout << "cnt: " << cnt << endl;
        vec.push_back({pos, cnt});
        int dis;
        if(vec.size() >= 3){
            dis = pos - vec[vec.size() - 1 - 1 - 1].first;
            int ncnt = dis / d + 1;
            if(dis % d == 0){
                ncnt--;
            }
            int change = ncnt - cnt - vec[vec.size() - 1 - 1].second;
            if(change == maxminus){
                num++;
            }
            else if(change < maxminus){
                maxminus = change;
                num = 1;
            }
        }
        //cout << "maxminus: " << maxminus << " num: " << num << endl;
        pre = pos;
    }
    if(vec.size() >= 2){
        int dis = n - vec[vec.size() - 1 - 1].first;
        int ncnt = dis / d;
        int change = ncnt - vec[vec.size() - 1].second - (n - vec[vec.size() - 1].first) / d;
        if(change == maxminus){
            num++;
        }
        else if(change < maxminus){
            maxminus = change;
            num = 1;
        }
    }

    if(b[0] == 1 && maxminus == 0){
        num++;
    }
    int sum = 0;
    for(int i = 0; i < vec.size(); i++){
        sum += vec[i].second;
    }
    int dis = n - vec[vec.size() - 1].first;
    int ncnt = dis / d;
    sum += ncnt;
    sum += maxminus;
    cout << sum << " " << num << endl;
    //cout << endl;

}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        solve();
    }

    return 0;
}

 

C. Yet Another Permutation Problem

要求构造一个从1 到 n的permutation, 定义d_i = gcd(a_i, a_(i % mod + 1)), 要求构造的permutation中d_i的种类(不同的值)(distinct value)最多。

 

不难发现,对于一个数m,如果要使它和另一个比它小的数组合,求出最大公因数,那么这个数是 m / 2的时候(m % 2 == 0),是它所能得到的最大公因数。由于数字从 1 到 n,所以对于m (m % 2 == 0), 一定可以得到m / 2存在,而一个从1 到 n 的permutation,依题意所能得到的最多的d_i的数量,应该为n / 2,所以依照上述方法构造即可。

#include<iostream>
#include<vector>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
const int INF = 2e9;



void solve() {
    int n;
    cin >> n;
    vector<bool> vis(n + 1, 0);
    vector<int> ans;
    int ptr = n;
    int put = n;
    while(ptr > 0){
        if(!vis[put] && put % 2 == 0){
            while(!vis[put]){
                ans.push_back(put);
                vis[put] = true;
                put /= 2;
                if(put <= 0){
                    break;
                }
                if(put % 2 != 0){
                    if(!vis[put]){
                        ans.push_back(put);
                        vis[put] = true;
                    }
                    break;
                }
            }
        }
        else if(!vis[put]){
            ans.push_back(put);
            vis[put] = true;
        }
        else{
            while(vis[ptr]){
                ptr--;
            }
        }
        put = ptr;
    }

    for(auto e: ans){
        cout << e << " ";
    }
    cout << endl;
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    int t = 1;
    cin >> t;
    while (t--) {
        solve();
    }

    return 0;
}

 

标签:893,饼干,小贩,int,题解,pos,vec,Div,dis
From: https://www.cnblogs.com/kurish/p/17646583.html

相关文章

  • [AGC005C] Tree Restoring 题解
    比较简单的题。思路我们可以把一棵树抽象成一条极长的链上挂了很多的点。观察这样的树的性质。除去中间的每一个\(dis\)至少有两个点的\(a_i=dis\)。考虑这条链的长度为\(s\)。那么对于中间的点,我们可以分两种情况讨论。\(s\)为偶数那么我们必然要求在中间的权值只......
  • hive sql运行时候reduce 只有2个问题解决
    我们在explansql时候发现width是负数,事实上原因width是通过dataSize/rowNum计算出来的,这两个参数都是在执行计划中根据每个operator通过stats计算出来的。对于selectquery来说,datasize是根据columnstats、尤其是non-null的数据计算出来的,这些non-nullvalue按照如下公......
  • RTSP/Onvif流媒体服务器EasyNVR安防视频平台一直提示网络请求失败的问题解决方案
    EasyNVR平台优秀的视频能力在于通过RTSP/ONVIF协议,将前端接入设备的音视频资源进行采集,并转码成适合全平台、全终端分发的视频流格式,包括RTMP、RTSP、FLV、HLS、WebRTC等格式。有用户反馈,EasyNVR使用过程中,突然提示网络请求失败,视频也无法播放,请求我们协助排查。此前我......
  • 安防视频监控平台EasyCVR视频集中存储平台接入RTSP设备出现离线情况的问题解决方案
    安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力,也具备接入AI智能分析的能......
  • UVA1589 象棋 题解
    0.题目大意在一个\(10\times9\)的网格上,可以游玩象棋。在本题中,我们考虑如下几个简化的规则:每一个棋子下在交点上,一个交点不能同时有两个棋子;棋盘的左上角为\((1,1)\),右下角为\((10,9)\);当一个棋子移动到它的敌人的棋子上,就说敌方的棋子要被“吃掉”。当棋盘上的“将”有......
  • tablestore依赖问题解决
    依赖引入最新版本<dependency><groupId>com.aliyun.openservices</groupId><artifactId>tablestore</artifactId><version>5.16.0</version></dependency>执行如下方法,报错下面2个错误信息,如下图:错误一:错误二:错误原因:JavaSDK依赖2......
  • YACS 2023年8月月赛 乙组 T3 香槟塔 题解
    题目链接乙组中比较好的一道思维题。首先考虑暴力,如果没满就倒满了就往下继续倒,直到倒完或溢出为止,但如果开始就全满然后每次都从最上面倒那么$O(n^2)$就超时了。我们希望找到一个数据结构(当然不是也行)能够快速得到从某个位置向下(包括当前位置)第一个没满的香槟塔,显然并查集。......
  • YACS 2023年8月月赛 乙组 T1 最长回文 题解
    题目链接小清新的区间DP题。看到数据范围以及回文一眼盯真得到是区间DP。设$f[i][j]$为区间$[i,j]$成为回文串最少要经过几次操作,转移一个个看。首先可以删掉第$j$个,$f[i][j]=\min(f[i][j],f[i][j-1]+1)$,同理也可以删掉第$i$个,$f[i][j]=\min(f[i][j],f[i+1][j]+1)$......
  • YACS 2023年6月月赛 乙组 T3 工作安排 题解
    这道题是乙组里比较新奇的一题,本来一眼看下来不会,后来蒙了个按照单位时间内收到罚款排序居然对了,十分意外。简单的证明一下:假设有两个工作,时间分别为$t_1$$f_1$$t_2$$f_2$,假设把第一个放在前面更优,前面的罚款不变。则有$t_1\timesf_1+(t_1+t_2)\timesf_2<t_2\timesf_2+(......
  • [刷题笔记] [【LGR-155-Div.3】T4] Luogu P9572 「NnOI R2-T4」Colorful Days♪
    ProblemDescription有两个数组\(A,B\),我们可以将\(A\)数组无限次重复拼接。求最少需要多少次拼接使得拼接后的\(A,B\)的最长公共子序列最大。Analysis我们要学会从题目中找到一些信息,比如说本题的数据范围:对于\(100\%\)的数据,保证\(1\leqn,m,S_i,T_i\le10^6\),\(......