Codeforces Round #767 (Div. 2)(A B C D E F1 F2)

Posted 斗奋力努

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #767 (Div. 2)(A B C D E F1 F2)相关的知识,希望对你有一定的参考价值。

Codeforces Round #767 (Div. 2)(A B C D E F1 F2)

A. Download More RAM
题意:问最多可以有多大RAM,当前RAM大于等于a[i]时,可以使RAM增加b[i]
思路:暴力+贪心,就将n个RAM参照a[i]从小到大排序就行了。

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int>PII;
const int N=1005;
int n,k;
PII a[N];

void solve()
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++) scanf("%d",&a[i].first);
    for(int i=1;i<=n;i++) scanf("%d",&a[i].second);
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++)
        if(k>=a[i].first) k+=a[i].second;
    
    printf("%d\\n",k);


int main()
    int t;scanf("%d",&t);
    while(t--) solve();

B. GCD Arrays
题意:在区间[l,r]中所有整数构成的集合中进行k次操作,每次操作是选择集合中的两次数,将他们删去,把他们的乘积加入集合。问最后集合所有数的gcd是否大于1
思路:因为初始是连续的数,所有我就直接猜了一下当集合中的奇数个数小于等于k时,或者集合初始只有一个数时(需要特判掉这个),就是YES,否则就是NO。(好像是保证奇偶结合还是啥的)

#include<bits/stdc++.h>
using namespace std;
int l,r,k;

void solve()
    scanf("%d%d%d",&l,&r,&k);
    int len;
    if(l%2==1) len=(r-l+2)/2;
    else len=(r-l+1)/2;
    if(k>=len) puts("YES");
    else if(l==r&&l!=1) puts("YES");
    else puts("NO");


int main()
    int t;scanf("%d",&t);
    while(t--) solve();

C. Meximum Array
题意:给一个长度为n的序列a,每次从开头取一截数字,将该截数字删去,同时在b序列中加入这截数字的MEX,要求输出字典序最大的b序列

思路:直接记录每种数字的位置,循环时拿now代表当前需要的数字,①:如果还有该数字,就代表可以选到now,则now+1,去讨论now+1是否还存在now+1,同时用p记录本次取数(1~now)要到达的最右端 p = m a x ( p , p o s [ n o w ] . b a c k ( ) ) , n o w + + ; p=max(p,pos[now].back()),now++; p=max(p,pos[now].back()),now++;
②:如果没有该数字了,则将now加入b序列,同时将数字(1~now-1)中所有小于p位置的数去掉,这是本次使用过的,同时将now=0重新开始循环。
结束后要是now还有值,也需要加入b序列,应该取到最后没有数了,也没有将now置为0,即此时还在一个循环中。
最后一次循环的右端点后面还有多少数就加多少个0到b序列

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
int n,a[N],num[N];
vector<int>ans;
vector<int>pos[N];

void solve()
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        int x;scanf("%d",&x);
        pos[x].push_back(i);
    
    for(int i=0;i<=n;i++) reverse(pos[i].begin(),pos[i].end());
    int now=0,p=0;
    while(pos[0].size())
        if(pos[now].size()) p=max(p,pos[now].back()),now++;
        else
            ans.push_back(now);
            for(int i=0;i<now;i++)
                while(pos[i].size()&&pos[i].back()<=p) pos[i].pop_back();
            
            now=0;
        
    
    if(now) ans.push_back(now);
    for(int i=0;i<=n;i++)
        while(pos[i].size()&&pos[i].back()<=p) pos[i].pop_back();
        while(pos[i].size()) ans.push_back(0),pos[i].pop_back();
    
    int len=ans.size();
    printf("%d\\n",len);
    for(int i=0;i<len;i++) printf("%d%c",ans[i],(i==len-1)?'\\n':' ');
    ans.clear();


int main()
    int t;scanf("%d",&t);
    while(t--) solve();

D. Peculiar Movie Preferences

题意:在n个字符串中,按顺序选择一些字符串,能否构成回文串。
思路:每个字符串的长度<=3,所以拿map记录,暴力循环就行了。
可以的情况有
一个字符串:
①存在长度为1的字符串 (如a、b、c…)
②存在形如AA的字符串(如aa、bb、cc…)
③存在形如ABA或AAA的字符串(如aaa、aba、aca…)
两个字符串:
④2+2,即形如AB+BA(如ab+ba)
⑤2+3,即形如AB+CBA或AB+BBA(如ab+cba、ab+bba)
⑥3+2,即形如ABC+BA或ABB+BA(如abc+ba、abb+ba)
⑦3+3,即形如ABC+CBA或ABB+BBA(如abc+cba、abb+bba)
以上都不存在,则一定是没有了。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,flag;
string s[N];
map<string,int>mp;

void input()
    flag=false,mp.clear();
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>s[i];
        int len=s[i].length();
        if(len==1) flag=true; //单个字母
        else if(len==2)
            if(s[i][0]==s[i][1]) flag=true;//类似aa的形式
        
        else
            if(s[i][0]==s[i][2]) flag=true;//类似aba的形式
        
    


void solve()
    input();
    if(flag) puts("YES");return;
    for(int i=1;i<=n;i++)
        int len=s[i].length();
        if(len==2)
            string nows;
            nows.push_back(s[i][1]);
            nows.push_back(s[i][0]);
            if(mp.find(nows)!=mp.end())puts("YES");return;
            for(int j=0;j<26;j++)
                string tes;
                tes+=nows;
                tes.push_back(j+'a');
                if(mp.find(tes)!=mp.end())puts("YES");return;
            
            mp[s[i]]=1;
        
        else
            string nows1;
            nows1.push_back(s[i][2]);
            nows1.push_back(s[i][1]);
            nows1.push_back(s[i][0]);
            if(mp.find(nows1)!=mp.end())puts("YES");return;    
            string nows2;
            nows2.push_back(s[i][2]);
            nows2.push_back(s[i][1]);        
            if(mp.find(nows2)!=mp.end())puts("YES");return;
            mp[s[i]]=1;
        
    
    puts("NO");


int main()
    int t;cin>>t;
    while(t--) solve();

E. Grid Xor

题意:给定一个n*n的矩阵,矩阵中点(i,j)的值为其四周的格子的异或值组成,要我们求所有格子的的数的异或值。保证n是偶数
思路:发现当某个点的四周都还未加入异或值时,选择该位置的数,就可以将四周没加入数加入异或值,发现在n为偶数时一定成立。(具体证明过程自证,我是画图找规律得出的)

#include<bits/stdc++.h>
using namespace std;
const int N=1005;
int n,a[N][N];
int dx[]=-1,1,0,0;
int dy[]=0,0,-1,1;

void solve()
    scanf("%d",&n);
    memset(a,0,sizeof(a));
    int sum=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            int x;scanf("%d",&x);
            bool flag=true;
            for(int k=0;k<4;k++)
                int nx=i+dx[k];
                int ny=j+dy[k];
                if(a[nx][ny]!=0)flag=false;break;
            
            if(flag)
                for(int k=0;k<4;k++)
                    int nx=i+dx[k];
                    int ny=j+dy[k];
                    a[nx][ny]=1;
                
                sum^=x;
            
        
    
    printf("%d\\n",sum);


int main()
    int t;scanf("%d",&t);
    while(t--) solve();

F1. Game on Sum (Easy Version)

题意:n轮游戏,每轮一个数,可以加上或减去,但至少加上的轮数要是m轮,每个数的范围为[0,k]的实数,问最终得分多少
思路:n的范围2000,可以 O ( n m ) O(nm) O(nm)
d p [ i ] [ j ] 代 表 剩 下 i 轮 选 择 , 还 需 要 做 j 次 加 法 的 得 分 dp[i][j]代表剩下i轮选择,还需要做j次加法的得分 dp[i][j]ij
d p [ i ] [ j ] = m i n ( x + d p [ i − 1 ] [ j − 1 ] , − x + d p [ i − 1 ] [ j ] ) dp[i][j]=min(x+dp[i-1][j-1],-x+dp[i-1][j]) dp[i][j]=min(x+dp[i1][j1],x+dp[iCodeforces Round #767 (Div. 2) A ~ D

Codeforces Round #767 (Div. 2) ABCD题解

Codeforces Round #767 (Div. 2)(A B C D E F1 F2)

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

CodeForces 767E(贪心)