• Codeforces Round #641 (Div. 2)


    A. Orac and Factors

    题意:每次 N 加上N的最小质因子,执行M次

    题解:暴力模拟。先判断是不是质数,来减少时间,然后在M次执行中,N可能会成为偶数X,那么,接下来的质因子都为2,那么就是X+=2*T,T代表剩余多少次操作

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <list>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <iomanip>
    #define ull unsigned long long
    #define ll long long
    #define pb push_back
    #define all(vc) vc.begin() , vc.end()
    #define rep(i,start,end) for(int i=start;i<=end;i++)
    #define per(i,end,start) for(int i=end;i>=start;i--)
    #define tle ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    #define lc now<<1
    #define rc now<<1|1
    ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    using namespace std;
    const int mod = 998244353;
    const int mxn = 1e6 +7;
    int _,n,m,t,k,u,v,ans,cnt,ok,lim,len,tmp;
    int pre[mxn] , head[mxn];
    struct node {int u,v,w,nx;}e[mxn];
    bool vis[mxn];
    bool isPrime_3(int num)
    {
         if(num==1)
            return 0;
         if(num==2||num==3)
            return 1;
         if(num%6!=1&&num%6!=5)
            return 0;
         int tmp=sqrt(num);
         for(int i=5;i<=tmp;i+=6)
            if(num%i==0||num%(i+2)==0)
               return 0;
         return 1;
    }
    int main()
    {
        for(cin>>t;t;t--)
        {
            cin>>n>>m;
            if(n%2==0) cout<<n+(m*2)<<endl;
            else
            {
                if(isPrime_3(n)) n+=n , m--;
                for(int i=2;i<=n;i++)
                {
                    if(n%i==0)
                    {
                        m--;
                        n+=i;
                        if(n%2==0){
                            n+=m*2;
                            break;
                        }
                    }
                }
                cout<<n<<endl;
            }
     
        }
    }
    View Code

    B - Orac and Models

    题意:在满足下标成倍数增长的情况下,找到最长的上升序列,

    题解:DP的思想,每次更新下标X的倍数,n*logn,不会T,然后每次对第一个数进行特判

    外引:Alyona and Spreadsheet ,思路的话可以看看这个题,最近做题遇见的,算思想类似题

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <list>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    #include <iomanip>
    #define ull unsigned long long
    #define ll long long
    #define pb push_back
    #define all(vc) vc.begin() , vc.end()
    #define rep(i,start,end) for(int i=start;i<=end;i++)
    #define per(i,end,start) for(int i=end;i>=start;i--)
    #define tle ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    #define lc now<<1
    #define rc now<<1|1
    ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    using namespace std;
    const int mod = 998244353;
    const int mxn = 2e5 +7;
    int _,n,m,t,k,u,v,ans,cnt,ok,lim,len,tmp;
    int a[mxn] , c[mxn] , b[mxn];
    struct node {int u,v,w,nx;}e[mxn];
    bool vis[mxn];
    int main()
    {
        for(cin>>t;t;t--)
        {
            cin>>n;
            for(int i=1;i<=n;i++) cin>>a[i] ,b[i] = 1 ;
            for(int i=2;i<=n;i++)
            {
                int tmp = a[i];
                if(a[i]>a[1]) b[i] = max(b[i],2);
                for(int j=2*i;j<=n;j+=i)
                {
                    if(a[j]>tmp)
                        b[j] = max(b[j] , b[i]+1 );
                    /// cout<<j<<" "<<b[j]<<endl;
                }
            }
            ans = 0 ;
            for(int i=1;i<=n;i++)
            ans = max(ans,b[i]);
            cout<<ans<<endl;
     
        }
    }
    View Code

     Orac and Medians

    题意:能否将给定的序列全部变为K

    题解:先判断是否存在K,然后,可以把一段序列变为K的条件是不是存在 K 的左边或者右边大于等于K就可以?对,这是一种方法

      那么,如果是类似于7 8 1 2 6 2 3 7 8 这样的序列呢,我是不是可以先变成7 8 7 7 6 6 6 6 6 ?再逆向变成 6 6 6 6 6 6 6 6 6

      那么,也就是如果存在下标为 x x+1 x+2 中 arr【X】 ,arr【 x+2】 >=K就可以变成max ( arr【X】,arr【 x+2】),而 max 也大于等于K,那么最后就可以选择两个或者三个一组的去全部变成K,但我们只需要知道存在不存在这样的结构就可以,并不需要去管如何将序列全部变成 K

      那么,也就是最终只需要判断是否存在K,以及是否存在( arr【x】=K,arr【x+1】>=k 或者 arr【x-1】>= K) || (arr【x】>=K && arr【x+2】>=K)两个条件的任意一个就可以

    代码的话上一位大佬的(我的代码四次遍历+条件的判断,以及2次特判,代码及其丑陋)

      

     #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<map>
    using namespace std;
    int n, w[101000], K;
    void Solve(){
        int i, ck=0;
        scanf("%d%d",&n,&K);
        for(i=1;i<=n;i++){
            scanf("%d",&w[i]);
            if(w[i]==K)ck=1;
        }
        if(!ck){
            puts("no");
            return;
        }
        if(n==1){
            puts("yes");
            return;
        }
        for(i=1;i<n;i++){
            if(w[i]>=K&&w[i+1]>=K){
                puts("yes");
                return;
            }
        }
        for(i=1;i<n-1;i++){
            if(w[i]>=K&&w[i+2]>=K){
                puts("yes");
                return;
            }
        }
        puts("no");
    }
    int main(){
        int TC;
        scanf("%d",&TC);
        while(TC--){
            Solve();
        }
    }
    代码源自CF:ainta
    所遇皆星河
  • 相关阅读:
    Linux:文件解压与压缩
    Linux:环境变量
    Linux:Vim
    Linux:目录&文件基本操作
    Linux:文件权限
    Linux:用户&用户组操作
    Linux:Shell 常用通配符
    Linux:常用shell快捷键
    Linux:Linux 重要人物
    架构:层次化
  • 原文地址:https://www.cnblogs.com/Shallow-dream/p/12880821.html
Copyright © 2020-2023  润新知