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

 

posted @ 2020-05-13 10:23  __MEET  阅读(175)  评论(0编辑  收藏  举报