Daily Practice 1st: Codeforces Round #767 (Div. 2)

忘了当时这一场为什么没打了,,,VP一波,,啊当然还是菜的可以

A. Download More RAM

打开第i个程序需要a[i]的空间,关闭该程序后会使空间增大b[i],问最大的储存空间是多少。

思路:结构体排序,先把打开需要空间小的放在前面,再就是打开后增加内存大的放在前面,遍历相加即可。

AC Code:

#include <bits/stdc++.h>

template <typename T>
inline void read(T &x) {
	x = 0;
	int f = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0', ch = getchar();
	}
	x *= f;
}

template <typename T>
void write(T x) {
	if (x < 0)
		putchar('-'), x = -x;
	if (x > 9)
		print(x / 10);
	putchar(x % 10 + '0');
}

#define INF 0x3f3f3f3f
typedef long long ll;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int N = 1e2 + 5;
int t,n,k;

struct node{
    int a,b;
}e[N];

bool cmp(node a,node b){
    if(a.a<b.a) return true;
    else if(a.a==b.a&&a.b>b.b) return true;
    else return false;
}

int main() {
//	freopen("test.in","r",stdin);
//  freopen("output.in", "w", stdout);
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
    std::cin>>t;
    while(t--){
        std::cin>>n>>k;
        for(int i=1;i<=n;i++) std::cin>>e[i].a;
        for(int i=1;i<=n;i++) std::cin>>e[i].b;
        std::sort(e+1,e+1+n,cmp);
        int ans=k;
        for(int i=1;i<=n;i++){
            if(e[i].a<=ans)
                ans+=e[i].b;
            else break;
        }
        std::cout<<ans<<'\n';
    }
	return 0;
}

B. GCD Arrays

给出一个区间[l,r],数组为该区间内的所有数,可以进行如下操作:选出两个数拿出数组,将它们的乘积放入数组,问能否通过k次操作使这个数组的gcd>1。

思路: 分情况讨论,l==r==1时,不能满足条件;l==r且l和r!=1时,满足条件;其他情况下,当k<数组中奇数个数时,不满足条件,反之满足条件。这样的基础是gcd为2。

AC Code:

#include <bits/stdc++.h>

template <typename T>
inline void read(T &x) {
	x = 0;
	int f = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0', ch = getchar();
	}
	x *= f;
}

template <typename T>
void write(T x) {
	if (x < 0)
		putchar('-'), x = -x;
	if (x > 9)
		print(x / 10);
	putchar(x % 10 + '0');
}

#define INF 0x3f3f3f3f
typedef long long ll;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int N = 1e2 + 5;
int t,l,r,k;

int getcnt(int l,int r){
    if((l%2==1)&&(r%2==0)||(l%2==0)&&(r%2==1))
        return (r-l+1)/2;
    else if(l%2==1)
        return r-l+1-(r-l+1)/2;
    else
        return (r-l+1)/2;
}

int main() {
//	freopen("test.in","r",stdin);
//  freopen("output.in", "w", stdout);
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
    std::cin>>t;
    while(t--){
        std::cin>>l>>r>>k;
        if(l==r&&l==1) std::cout<<"NO"<<'\n';
        else if(l==r&&l!=1) std::cout<<"YES"<<'\n';
        else if(getcnt(l,r)>k) std::cout<<"NO"<<'\n';
        else std::cout<<"YES"<<'\n';
    }
	return 0;
}

C. Meximum Array

给出一个数列,每次找一个k,把数组中前k个数的MEX作为b数组的元素,问怎样构造b数组使其字典序最大。

思路:想法并不难,但是代码emmm,,先找到最大的MEX,就是第一个,因为要满足字典序最大;剩下的再找最大的MEX,以此类推,直到数组没有元素为止。具体实现,每次当某个数的cnt为0时,对于下一个MEX的取值而言,就是该数和现在的MEX值取最小值,要想满足一个数为MEX,用set存储后判断set.size()即可。

AC Code:

#include <bits/stdc++.h>

template <typename T>
inline void read(T &x) {
	x = 0;
	int f = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0', ch = getchar();
	}
	x *= f;
}

template <typename T>
void write(T x) {
	if (x < 0)
		putchar('-'), x = -x;
	if (x > 9)
		print(x / 10);
	putchar(x % 10 + '0');
}

#define INF 0x3f3f3f3f
typedef long long ll;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int N = 2e5 + 5;
int t,n;
int a[N],cnt[N];

int main() {
//	freopen("test.in","r",stdin);
//  freopen("output.in", "w", stdout);
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
    std::cin>>t;
    while(t--){
        std::cin>>n;
        memset(cnt,0,sizeof(cnt));
        for(int i=1;i<=n;i++){
            std::cin>>a[i];
            cnt[a[i]]++;
        }
        int pos;
        for(int i=0;i<=n;i++){
            if(cnt[i]==0){
                pos=i;
                break;
            }
        }
        int k=0;
        std::set<int>ss;
        std::vector<int>vec;
        int nex=pos;
        for(int i=1;i<=n;i++){
            if(pos==0){
                vec.push_back(0);
                continue;
            }
            if(a[i]<pos){
                cnt[a[i]]--;
                if(cnt[a[i]]==0)
                    nex=std::min(nex,a[i]);
                ss.insert(a[i]);
                if(ss.size()==pos){
                    vec.push_back(pos);
                    ss.clear();
                    pos=nex;
                }
            }
        }
        std::cout<<vec.size()<<'\n';
        for(int i=0;i<vec.size();i++){
            std::cout<<vec[i]<<" \n"[i==vec.size()-1];
        }
    }
	return 0;
}

D. Peculiar Movie Preferences

给出n个最长为3的字符串,问是否可以通过删去其中的某些字符串使得这些字符串按顺序相连得到回文串,删除操作只能删去从开头到某一个,或者从末尾向前的某一个。

思路: 如果长度为1,则本身就是回文串,最多把其他的全都删掉;如果是长度为2的,那可以与长度为2或长度为3的组成回文串;长度为3的,可以与长度为2或者长度为3的组成回文串。具体实现,分情况讨论即可,分别用两个set存长度为2和长度为3的串即可。

AC Code:

#include <bits/stdc++.h>

template <typename T>
inline void read(T &x) {
	x = 0;
	int f = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - '0', ch = getchar();
	}
	x *= f;
}

template <typename T>
void write(T x) {
	if (x < 0)
		putchar('-'), x = -x;
	if (x > 9)
		print(x / 10);
	putchar(x % 10 + '0');
}

#define INF 0x3f3f3f3f
typedef long long ll;
const double PI = acos(-1);
const double eps = 1e-6;
const int mod = 1e9 + 7;
const int N = 1e6 + 5;
int t,n;
std::string s;

int main() {
//	freopen("test.in","r",stdin);
//  freopen("output.in", "w", stdout);
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	std::cout.tie(0);
    std::cin>>t;
    while(t--){
        std::cin>>n;
        bool flag=false;
        std::set<std::string>two,three;
        for(int i=0;i<n;i++){
            std::cin>>s;
            int len=s.length();
            if(len==1) flag=true;
            else if(len==2){
                if(s[0]==s[1]) flag=true;
                else{
                    std::string c=s;
                    reverse(c.begin(),c.end());
                    if(two.count(c))
                        flag=true;
                    for(char i='a';i<='z';i++){
                        if(three.count(c+i))
                            flag=true;
                    }
                    two.insert(s);
                }
            }
            else if(len==3){
                if(s[0]==s[2]) flag=true;
                else{
                    std::string x=s;
                    reverse(x.begin(),x.end());
                    x.pop_back();
                    if(two.count(x)) flag=true;
                    x=s;
                    reverse(x.begin(),x.end());
                    if(three.count(x)) flag=true;
                    three.insert(s);
                }
            }
        }
        std::cout<<(flag?"YES":"NO")<<'\n';
    }
	return 0;
}

坚持就是胜利!

若有错误请指教orzorz

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值