ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Codeforces Round #805 (Div. 3) A C D E F题解

2022-07-23 06:00:07  阅读:126  来源: 互联网

标签:int 题解 Codeforces long while ans Div include define


A.

problem A

点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<string>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
typedef long long ll;
using namespace std;
typedef unsigned long long int ull;
#define maxn 200005
#define ms(x) memset(x,0,sizeof(x))
#define Inf 0x7fffffff
#define inf 0x3f3f3f3f
const int mod = 1e9 + 7;
#define pi acos(-1.0)
#define pii pair<int,int>
#define eps 1e-5
#define pll pair<ll,ll>
#define lson 2*x
#define rson 2*x+1

long long  qupower(int a, int b) {
	long long  ans = 1;
	while (b) {
		if (b & 1)ans = ans * a;
		b >>= 1;
		a = a * a;
	}
	return ans;
}

inline int read() {
	int an = 0, x = 1; char c = getchar();
	while (c > '9' || c < '0') {
		if (c == '-') {
			x = -1; 
		}
		c = getchar();
	}
	while (c >= '0'&&c <= '9') {
		an = an * 10 + c - '0'; c = getchar();
	}
	return an * x;
}

int t;
int m;

int find_round(int x){
    int ans = 1;
    while(ans<=x){ans = ans*10;}
    return ans/10;
}

int main(){
    //ios::sync_with_stdio(false);
    t = read();
    while(t--){
        scanf("%d",&m);
        cout<<m - find_round(m)<<endl;
    }
}

C.

problem C
给定一个序列,询问是否存在一个数对 (\(a,b\)) 在序列中。 暴力做法:枚举 \(a\),看 \(a\) 后面的序列中是否出现 \(b\), 复杂度 \(O(N^2)\) 不允许。实际上我们可以用 \(vector\) 来记录每个数出现的位置,显然这些位置是从小到大的。如果 \(a\) 的位置区间最小值大于 \(b\) 的位置区间最大值,显然不可能

点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<string>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
typedef long long ll;
using namespace std;
typedef unsigned long long int ull;
#define maxn 200005
#define ms(x) memset(x,0,sizeof(x))
#define Inf 0x7fffffff
#define inf 0x3f3f3f3f
const int mod = 1e9 + 7;
#define pi acos(-1.0)
#define pii pair<int,int>
#define eps 1e-5
#define pll pair<ll,ll>
#define lson 2*x
#define rson 2*x+1

long long  qupower(int a, int b) {
	long long  ans = 1;
	while (b) {
		if (b & 1)ans = ans * a;
		b >>= 1;
		a = a * a;
	}
	return ans;
}

inline int read() {
	int an = 0, x = 1; char c = getchar();
	while (c > '9' || c < '0') {
		if (c == '-') {
			x = -1; 
		}
		c = getchar();
	}
	while (c >= '0'&&c <= '9') {
		an = an * 10 + c - '0'; c = getchar();
	}
	return an * x;
}
int n;
int t;

int u[200005];


int main(){
    //ios::sync_with_stdio(false);
    cin>>t;
    while(t--){
        cout<<endl;
        n = read();
        int k = read();
        ms(u);
        map<int, pair<int,int> > loc;

        for(int i=0;i<n;i++)u[i] = read();
        for(int i=0;i<n;i++){
            if(!loc.count(u[i])){
                loc[u[i]] = make_pair(i,i);
            }
            else{
                loc[u[i]].second = i;
            }
        }

        while(k--){
            int a =read(), b = read();
            if(!loc.count(a) || !loc.count(b) || loc[a].first>loc[b].second){
                printf("NO\n");
            }
            else{
                printf("YES\n");
            }
        }
    }

}

D.

problem D
给定一个字符串,以及一个限制 \(p\),删除最小数量的字符使得字符串的 \(sum\leq p\). 并且保留字符串中字符原有的顺序。

那么我们贪心地去删除显然是选大的去删

点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<string>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
typedef long long ll;
using namespace std;
typedef unsigned long long int ull;
#define maxn 200005
#define ms(x) memset(x,0,sizeof(x))
#define Inf 0x7fffffff
#define inf 0x3f3f3f3f
const int mod = 1e9 + 7;
#define pi acos(-1.0)
#define pii pair<int,int>
#define eps 1e-5
#define pll pair<ll,ll>
#define lson 2*x
#define rson 2*x+1

long long  qupower(int a, int b) {
	long long  ans = 1;
	while (b) {
		if (b & 1)ans = ans * a;
		b >>= 1;
		a = a * a;
	}
	return ans;
}

inline int read() {
	int an = 0, x = 1; char c = getchar();
	while (c > '9' || c < '0') {
		if (c == '-') {
			x = -1; 
		}
		c = getchar();
	}
	while (c >= '0'&&c <= '9') {
		an = an * 10 + c - '0'; c = getchar();
	}
	return an * x;
}

int t;
string s;
int p;

int map_to_int(char x){
    return x-'a'+1;
}

vector<char> vec;
map<char,int> mp;

int cal_sum(string s){
    int n = s.length();
    int ans = 0;
    for(int i=0;i<n;i++){
        ans += (s[i]-'a'+1);
    }
    return ans;
}

int main(){
    //ios::sync_with_stdio(false);
    t = read();
    while(t--){
        cin>>s;
        int comp = cal_sum(s);
        cin>>p;
        if(p>=comp) cout<<s<<endl;
        
        else{
            vec.clear(); mp.clear();
            string ans="";
            int n = s.length();
            int Min = 30;
            for(int i=0;i<n;i++)vec.push_back(s[i]), Min = min(Min,map_to_int(s[i]));
            if(Min>p){
                cout<<""<<endl;
            }
            else{
                sort(vec.begin(),vec.end()); reverse(vec.begin(),vec.end());
                for(int i=0;i<n;i++){
            //    cout<<vec[i]<<" ";
                    if(comp-map_to_int(vec[i])<=p){
                        mp[vec[i]]++; break;
                    }
                    mp[vec[i]]++;comp -= map_to_int(vec[i]);
                }
                for(int i=0;i<n;i++){
                    if(mp[s[i]]==0){
                        ans = ans+s[i];
                    }
                    else mp[s[i]]--;
                }
                cout<<ans<<endl;
            }
        }
    }
}

E.

problem D
给定 \(n\) 个多米诺骨牌,且多米诺上的数字范围 \(1\sim n\),每个多米诺上面有 \(2\) 个数。问能否将这些分成两个集合,且每个集合里面的数字不一样。

思路:分成两个集合, 每个集合大小为 \(n\) ----> 每个集合的数字都不一样: 必须 \(1,2,...,n\) 都出现一次。不妨将多米诺上面的数字看作:\((x,y)\) 表示 \(x,y\) 之间有一条边。所以会形成一个个的小环。什么情况下才能满足条件呢?我们从一个点出发,遍历结束得到的环长度为偶数才可以,否则奇数环必然分到一个相同的元素。

点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<string>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
typedef long long ll;
using namespace std;
typedef unsigned long long int ull;
#define maxn 200005
#define ms(x) memset(x,0,sizeof(x))
#define Inf 0x7fffffff
#define inf 0x3f3f3f3f
const int mod = 1e9 + 7;
#define pi acos(-1.0)
#define pii pair<int,int>
#define eps 1e-5
#define pll pair<ll,ll>
#define lson 2*x
#define rson 2*x+1

long long  qupower(int a, int b) {
	long long  ans = 1;
	while (b) {
		if (b & 1)ans = ans * a;
		b >>= 1;
		a = a * a;
	}
	return ans;
}

inline int read() {
	int an = 0, x = 1; char c = getchar();
	while (c > '9' || c < '0') {
		if (c == '-') {
			x = -1; 
		}
		c = getchar();
	}
	while (c >= '0'&&c <= '9') {
		an = an * 10 + c - '0'; c = getchar();
	}
	return an * x;
}
int t;
map<int, vector<int> > edge;
int vis[200005];

int dfs(int x){
    vis[x] = 1;
    for(auto v: edge[x]){
        if(!vis[v])return dfs(v)+1;
    }
    return 1;
}

void solve(){
    int n = read();
    edge.clear(); ms(vis);
    bool fg = false;

    for(int i=0;i<n;i++){
        int a = read(), b = read();
        edge[a].push_back(b); edge[b].push_back(a);
        if(a==b || edge[a].size()>2 || edge[b].size()>2)fg = true;
    }
    if(fg){
        printf("NO\n");
        return;
    }
    for(int i=1;i<=n;i++){
        if(!vis[i]){
            if(dfs(i)%2){
                printf("NO\n");
                return;
            }
        }
    }
    printf("YES\n");
}

int main(){
    //ios::sync_with_stdio(false);
    t = read();
    while(t--){
        solve();
    }
}

F.

problem F
给定两个 \(multiset\), 只对其中一个集合的元素进行修改:

  • \(x \rightarrow 2x\)
  • \(x \rightarrow x/2\)

其中除以2是向下取整的。问能否通过这些操作把另一个集合变成和第一个集合一样。

思路: 不妨先将第一个集合的所有元素通通进行 \(/2\) 的操作只要 \(x\%2=0\),这样变成了一种 基元素。注意到此时的元素必然都是奇数,现在我们只需要采用操作2改变另一个集合即可,因为第一个操作只会使得元素变为偶数。

点击查看代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<string>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
typedef long long ll;
using namespace std;
typedef unsigned long long int ull;
#define maxn 200005
#define ms(x) memset(x,0,sizeof(x))
#define Inf 0x7fffffff
#define inf 0x3f3f3f3f
const int mod = 1e9 + 7;
#define pi acos(-1.0)
#define pii pair<int,int>
#define eps 1e-5
#define pll pair<ll,ll>
#define lson 2*x
#define rson 2*x+1

long long  qupower(int a, int b) {
	long long  ans = 1;
	while (b) {
		if (b & 1)ans = ans * a;
		b >>= 1;
		a = a * a;
	}
	return ans;
}

inline int read() {
	int an = 0, x = 1; char c = getchar();
	while (c > '9' || c < '0') {
		if (c == '-') {
			x = -1; 
		}
		c = getchar();
	}
	while (c >= '0'&&c <= '9') {
		an = an * 10 + c - '0'; c = getchar();
	}
	return an * x;
}

int t;
int n;

void solve(){
    n = read();
    multiset<int> a, b;
    for(int i=0;i<n;i++){
        int x = read();
        while(x%2==0)x/=2;
        a.insert(x);
    }

    for(int i=0;i<n;i++){
        int x = read(); b.insert(x);
    }

    while(!b.empty()){
        // max value of b
        int x = *b.rbegin();
        if(!a.count(x)){
            // cannot find x
            if(x==1) break;
            b.erase(b.find(x));b.insert(x/2);
        }
        else{
            // find x
            a.erase(a.find(x)); b.erase(b.find(x));
        }
    }
    if(b.empty()) printf("YES\n");
    else printf("NO\n");

}

int main(){
    //ios::sync_with_stdio(false);
    t = read();
    while(t--){
        solve();
    }
}

标签:int,题解,Codeforces,long,while,ans,Div,include,define
来源: https://www.cnblogs.com/xinyu04/p/16508429.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有