• Codeforces Round #697 (Div. 3)


    题目链接:https://codeforces.com/contest/1475

    A题:问你一个数字n是否有奇数的约数,并且这个数比1大

    • 直接除以2,如果除到最后不是1的话,就是YES,否则为NO
    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    
    int main()
    {
        int t;
        cin >> t;
        while(t --)
        {
            LL x;
            cin >> x;
            while(1){
                if(x % 2 == 0){
                    x = x / 2;
                }else{
                    break;
                }
            }
            
            if(x == 1){
                cout << "NO" << endl;
            }else{
                cout << "YES" << endl;
            }
            
        }
        
        return 0;
    }
    

    B题:问你一个数能否由 若干个 2020 + 若干个 2021

    • 可以打表,我是直接算的,差点被人hack掉,建议打表,把所有能被2020 和2021组成的数算出来
    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    
    int main()
    {
        int t;
        cin >> t;
        while(t --)
        {
            int n;
            cin >> n;
            
            int x = 2021,y = 2020;
            bool tf = false;
            for(int i = 0;i < 1000;i ++)
            {
                for(int j = 0;j < 1000;j ++)
                {
                    LL sum = x * i + y * j;
                    if(sum == n){
                        tf = true;
                        break;
                    }
                    else if(sum > n){
                        break;
                    }
                }
                if(tf){
                    break;
                }
            }
            
            if(tf){
                cout << "YES" << endl;
            }else{
                cout << "NO" << endl;
            }
        }
        
        return 0;
    }
    

    C题:应该问的是你最多能找出多少对舞伴,只能是 (a,b) && (c,d) 这里 a != c && b != d

    • 对于每一个人,直接找除了他本身以外的人和它的舞伴以外的人有多少个人,然后用总对数减去就Ok了,然后再加上他本身这一对
    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    const int N = 1e6 + 10;
    
    typedef pair<int,int> PII;
    PII p[N];
    
    int boy[N];
    int gril[N];
    int main()
    {
        int t;
        cin >> t;
        
        int a,b,k;
        
        while(t --)
        {
            cin >> a >> b >> k;
            
            
            for(int i = 0;i <= a;i ++) boy[i] = 0;
            for(int i = 0;i <= b;i ++) gril[i] = 0;
            
            for(int i = 0;i < k;i ++)
            {
                cin >> p[i].first;
                boy[p[i].first] ++;
            }
            for(int i = 0;i < k;i ++)
            {
                cin >> p[i].second;
                gril[p[i].second] ++;
            }
            LL ans = 0;
            for(int i = 0;i < k;i ++)
            {
                ans = ans + k - (boy[p[i].first] + gril[p[i].second] - 1);
              //  cout << ans << endl;
            }
            
            cout << ans / 2 << endl;
            
            
        }
        
        
        return 0;
    }
    

    D题:想让你清理至少m的内存,a数组是你可以清理文件的内存的大小,b数组是你清理当前文件需要花费的体力

    • 你需要花费少的体力在清理掉至少m内存,这里的b数组里面的数比较特殊,不是1就是2,如果是别的数字的话,可以用背包来做
    • 这里我直接找的官方题解
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    LL t,n,m;
    const int N = 1e6 + 10;
    int a[N];
    int b[N];
    
    int main()
    {
        cin >> t;
        while(t --)
        {
            cin >> n >> m;
            LL sum = 0;
            for(int i = 0;i < n;i ++){
                cin >> a[i];
                sum += a[i];
            }
            
            
            vector<int>v1;
            vector<int>v2;
            for(int i = 0;i < n;i ++)
            {
                cin >> b[i];
                if(b[i] == 1){
                    v1.push_back(a[i]);
                }else{
                    v2.push_back(a[i]);
                }
            }
            
            if(sum < m) 
            {
                cout << -1 << endl;
                continue;
            }
            
            sort(v1.begin(),v1.end());
            sort(v2.begin(),v2.end());
            reverse(v1.begin(),v1.end());
            
            sum = 0;
            int ans = 1e9;
            int j = 0;
            for(int i = 0;i < v2.size();i ++){
                sum += v2[i];
            }
            for(int i = 0;i <= v2.size();i ++){
                
                while(j < v1.size() && sum < m){
                    sum += v1[j];
                    j ++;
                }
                if(sum >= m){
                    ans = min(ans,(int)(v2.size() - i) * 2 + j);
                }
                
                if(i == v2.size()) continue;
                sum -= v2[i];
            }
            cout << ans << endl;
        }
        return 0;
    }
    

    E题:组合数模板

    #include <bits/stdc++.h>
    using namespace std;
    
    typedef long long LL;
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    typedef pair<int,int> PII;
    PII p[N];
    int a[N];
    
    LL qmi(LL a,LL b)
    {
        LL res = 1;
        while(b){
            if(b & 1) res = res * a % mod;
            a = a * a % mod;
            b = b >> 1;
        }
        return res;
    }
    LL fact[N],infact[N];
    //fact[i]表示i! % mod 的值
    //infact[i]表示i! % mod的逆元,用乘逆元来表示除法
    //组合数为:fact[a] * infact[a-b] % mod * infact[b] % mod
    LL C(LL a,LL b)
    {
        return fact[a] * infact[a-b] % mod * infact[b] % mod;
    }
    
    
    
    int main()
    {
        fact[0] = 1;
        infact[0] = 1;
        for(int i = 1; i < N; i++){
            fact[i] = fact[i-1] * i % mod;
            infact[i] = qmi(fact[i], mod - 2) % mod;
        }
        
        int t;
        cin >> t;
        int n,k;
        
        while(t --)
        {
            cin >> n >> k;
            vector<int>v;
            int x;
            
            for(int i = 0;i <= n;i ++){
                a[i] = 0;
            }
            
            for(int i = 0;i < n;i ++)
            {
                cin >> x;
                v.push_back(x);
                a[x] ++;
            }
            sort(v.begin(),v.end());
            reverse(v.begin(),v.end());
            
            int bk = k;
            
            for(int i = 0;i < n;i ++)
            {
                x = v[i];
                k --;
                if(k == 0) break;
            }
            k = bk;
            for(int i = 0;i < n;i ++)
            {
                if(v[i] == x){
                    break;
                }
                k --;
            }
            
          //  cout << k << endl;
            
            cout << C(a[x],k) << endl;
        }
        
        
        return 0;
    }
    

    F题:你可以修改一行,让0变成1,让1变成0,或者是修改一列,让0变成1,让1变成0

    • 题解中这样说道:对于某一行,至多会被修改一次,某一列也是如此,并且修改的顺序不会影响最终结果,所以我们先判断行,如果第一个数字不同就修改这一行,然后列也进行一样的操作
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    int t,n,m;
    
    const int N = 1100;
    
    char a[N][N];
    char b[N][N];
    int main()
    {
        cin >> t;
        while(t --)
        {
            cin >> n;
            for(int i = 0;i < n;i ++){
                cin >> a[i];
            }
            
            for(int j = 0;j < n;j ++){
                cin >> b[j];
            }
            
            for(int i = 0;i < n;i ++){
                if(a[0][i] != b[0][i]){
                    for(int k = 0;k < n;k ++){
                        a[k][i] = a[k][i] ^ 1;
                    }
                }
            }
            
            for(int i = 0;i < n;i ++){
                if(a[i][0] != b[i][0]){
                    for(int k = 0;k < n;k ++){
                        a[i][k] = a[i][k] ^ 1;
                    }
                }
            }
            
            bool flag = true;
            for(int i = 0;i < n;i ++){
                for(int j = 0;j < n;j ++){
                    if(a[i][j] != b[i][j]){
                        flag = false;
                    }
                }
            }
            
            if(flag){
                cout << "YES" << endl;
            }else{
                cout << "NO" << endl;
            }
            
            
        }
        
        
        return 0;
    }
    
    /*
    001
    001 
    001
    
    */
    

    G题:有点像这个题:https://ac.nowcoder.com/acm/contest/7501/A,不能说一模一样吧,但至少一模两样

    • 这个题求逆,那个题求正
    • 就是考察对筛法,首先大家肯定都知道排序,另外大家也都会去重,接下来就是状态方程的转移了
    • dp[i] 代表的以i为结尾的最长倍数子序列的长度是多少
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    int t,n,m;
    
    const int N = 2e6 + 10;
    
    vector<int> a;
    int dp[N];
    int st[N];
    int main()
    {
        cin >> t;
        while(t --)
        {
            cin >> n;
            a.clear();
            memset(dp,0,sizeof dp);
            memset(st,0,sizeof st);
            
            for(int i = 1;i <= n;i ++){
                int x;
                cin >> x;
                a.push_back(x);
                st[x] ++;
            }
            
            sort(a.begin(), a.end()); // 将所有值排序
            a.erase(unique(a.begin(), a.end()), a.end());
    
            for(int i = 0;i < a.size();i ++){
                dp[a[i]] = dp[a[i]] + st[a[i]];
                for(int j = 2;j  <= N + 10;j ++){
                    if(j * a[i] >= N) break;
                    if(st[j * a[i]])
                        dp[j * a[i]] = max(dp[a[i]] ,dp[j * a[i]]);
                }
            }
            int res = 0;
            for(int i = 0;i < a.size();i ++){
                res = max(dp[a[i]],res);
            }
            cout << n - res << endl;
        }
        return 0;
    }
    
    /*
    3 7 9 14 63
    
    */
    
    知足常乐!
  • 相关阅读:
    Pytorch cpu版离线安装:win10 + Anaconda + Pip
    离线配置Opencv-python: Anaconda3 + Pycharm+ Win10 + Python3.6
    HSmartWindowControl 之 摄像头实时显示( 使用 WPF )
    OpencvSharp 在WPF的Image控件中显示图像
    HSmartWindowControl 之 显示图像
    HSmartWindowControl之安装篇 (Visual Studio 2013 & Halcon 18)
    使用ILMerge 打包C# 绿色免安装版程序
    C# 日志输出工具库—log4net 安装、配置及简单应用
    Python:windows下scikit-learn 安装和更新
    C# 开源仪表盘库—Agauge App
  • 原文地址:https://www.cnblogs.com/yjsh/p/14348598.html
Copyright © 2020-2023  润新知