xinyu04

导航

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

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();
    }
}

posted on 2022-07-23 05:54  Blackzxy  阅读(34)  评论(0编辑  收藏  举报