Codeforces Round #606 (Div. 2, based on Technocup 2020 Elimination Round 4)

传送门:https://codeforces.com/contest/1277

A

求一下和 \(n\) 相同位数时有多少个是合法的,记为 \(x\),答案为 \(x+9(len(n)-1)\)。

我写的很丑 qwq。

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb push_back
#define eb emplace_back
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
using pii = pair<int, int>;
using pdd = pair<double, double>;
using vi = vector<int>;
using vvi = vector<vi>;
using vb = vector<bool>;
using vpii = vector<pii>;
using ll = long long;
using ull = unsigned long long;

#define int ll

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

int to_int(string s){
	int res=0;
	for(auto i: s) res=res*10+i-'0';
	return res;
}

signed main(){
	int T; cin>>T;
	while(T--){
		string s; cin>>s; int n=s.size();
		int res=(n-1)*9;
		
		int t=1;
		rep(i,1,n) t*=10;
		t=(t-1)/9;
		
		rep(i,1,10) if(i*t>to_int(s)){
			res+=i-1;
			break;
		}
		cout<<res<<endl;
	}	
    return 0;
}

B

处理出每个数最多可以除以 \(2\) 的次数,并将这个数最终能够变成的奇数用 map 存下来,键值就是上述的次数与之前的键值取 max

于是答案为 map 中所有键值的和。

见代码。

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb push_back
#define eb emplace_back
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
using pii = pair<int, int>;
using pdd = pair<double, double>;
using vi = vector<int>;
using vvi = vector<vi>;
using vb = vector<bool>;
using vpii = vector<pii>;
using ll = long long;
using ull = unsigned long long;

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

map<int, int> mp;

int main(){
	int T; cin>>T;
	while(T--){
		mp.clear();
		int n; read(n);
		rep(i,1,n){
			int v; read(v);
			int cnt=0; while(!(v&1)) v>>=1, cnt++;
			if(!mp.count(v)) mp[v]=cnt; 
			else mp[v]=max(mp[v], cnt);
		}
		
		int res=0;
		for(auto [x, y]: mp) res+=y;
		cout<<res<<endl;
	}	
    return 0;
}

C

题意:

给一个字符串,去掉最少的字符使得字符串不存在子串 one,two

决策:

注意到遇到 one 时无论如何决策都无法影响后面,所以我们直接将 n 干掉。

如果遇到 two,分两种情况:two 后面紧接 ne 或者后面不是 ne:对于前者,去掉 o 显然是最佳的,这样可以同时干掉 twoone,而对于后者我们直接选择去掉 w

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb push_back
#define eb emplace_back
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
using pii = pair<int, int>;
using pdd = pair<double, double>;
using vi = vector<int>;
using vvi = vector<vi>;
using vb = vector<bool>;
using vpii = vector<pii>;
using ll = long long;
using ull = unsigned long long;

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

int main(){
	int T; cin>>T;
	while(T--){
		string s; cin>>s; int n=s.size(); s=' '+s+"##";
		
		vi res;
		rep(i,1,n-2){
			string t;
			rep(j,i,i+2) t+=s[j];
			if(t=="one"){
				res.pb(i+1);
			}
			else if(t=="two"){
				string tmp; rep(j,i+3,i+4) tmp+=s[j];
				if(tmp=="ne") res.pb(i+2), i=i+2;
				else res.pb(i+1);
			}
		}
		
		cout<<res.size()<<endl;
		for(auto i: res) cout<<i<<' ';
		cout<<endl;
	}	
    return 0;
}

D

给 \(n\) 个 \(01\) 串,你可以对它们进行翻转操作,求最少的翻转次数使得:

  • 所有串不重复。
  • 所有串可以以某种顺序接龙(也就是前串的尾等于后串的头)。

要求输出方案,如果无解就输出 -1

步骤

这题我写了接近 1h, Orz。

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb push_back
#define eb emplace_back
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b

#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
using pii = pair<int, int>;
using pdd = pair<double, double>;
using vi = vector<int>;
using vvi = vector<vi>;
using vb = vector<bool>;
using vpii = vector<pii>;
using ll = long long;
using ull = unsigned long long;

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

const int N=2e5+5;
map<string, int> buf;
string str[N];
bool vis[N];

int get(string s){
	string t;
	t+=s[0]; t+=s[s.size()-1];
	if(t=="00") return 1;
	else if(t=="01") return 2;
	else if(t=="10") return 3;
	else return 4;
}

bool ok(string s){
	reverse(all(s));
	return !buf.count(s);
}

int main(){
	int T; cin>>T;
	while(T--){
		int cnt[5]={0};
		int n; read(n);
		rep(i,1,n) vis[i]=false;
		buf.clear();
		
		bool ed=false;
		vi res;
		rep(i,1,n){
			string s; cin>>s; str[i]=s;
			
			if(!buf.count(s)){
				buf[s]=i;
				cnt[get(s)]++;
			}
			else{
				reverse(all(s));
				if(buf.count(s)){
					ed=true;
				}
				else{
					buf[s]=i; cnt[get(s)]++;
					reverse(all(s)); res.pb(i);
					vis[i]=vis[buf[s]]=true;
				}
			}
		}
		
		if(ed){
			puts("-1");
			continue;
		}
		if(cnt[1] && cnt[4] && !cnt[2] && !cnt[3]){
			puts("-1");
			continue;
		}
		
		rep(i,1,n){
			if(vis[i]) continue;
			if(cnt[2]-cnt[3]>1 && get(str[i])==2 && ok(str[i])){
				res.pb(i);
				cnt[2]--, cnt[3]++;
			}
			else if(cnt[3]-cnt[2]>1 && get(str[i])==3 && ok(str[i])){
				res.pb(i);
				cnt[3]--, cnt[2]++;
			}
		}
		
		if(abs(cnt[3]-cnt[2])<=1){
			cout<<res.size()<<endl;
			for(auto i: res) cout<<i<<' ';
			cout<<endl;
		}
		else puts("-1");
	}	
    return 0;
}

E

我们记从 \(a\) 出发不经过 \(b\) 能到达的点集为 \(col_1\),从 \(b\) 出发不经过 \(a\) 能到达的点集为 \(col_2\),且 \(col_1\cap col_2 =col_3\)。

则答案为 \(size(col_1-col_3)\times size(col_2-col_3)\)。

#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;

#define endl '\n'
#define debug(x) cerr << #x << ": " << x << endl
#define pb push_back
#define eb emplace_back
#define set0(a) memset(a,0,sizeof(a))
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define ceil(a,b) (a+(b-1))/b
#define INF 0x3f3f3f3f
#define ll_INF 0x7f7f7f7f7f7f7f7f
using pii = pair<int, int>;
using pdd = pair<double, double>;
using vi = vector<int>;
using vvi = vector<vi>;
using vb = vector<bool>;
using vpii = vector<pii>;
using ll = long long;
using ull = unsigned long long;

inline void read(int &x) {
    int s=0;x=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {if(ch=='-')x=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
    x*=s;
}

const int N=2e5+5, M=500050<<1;

int n, m, a, b;
struct node{
	int to, next;
}e[M];

int h[N], tot;

void add(int u, int v){
	e[tot].to=v, e[tot].next=h[u], h[u]=tot++;
}

int col[N];
bool vis[N];

void dfs(int u, int color, int pd){
	if(u==pd) return;
	vis[u]=true;
	col[u]+=color;
	for(int i=h[u]; ~i; i=e[i].next){
		int go=e[i].to;
		if(vis[go]) continue;
		dfs(go, color, pd);
	}
}

int main(){
	int T; cin>>T;
	while(T--){
		read(n), read(m), read(a), read(b);
		rep(i,1,n) h[i]=-1, vis[i]=col[i]=0; tot=0;
		
		rep(i,1,m){
			int u, v; read(u), read(v);
			add(u, v), add(v, u);
		}
		
		dfs(a, 1, b);
		rep(i,1,n) vis[i]=false;
		dfs(b, 2, a);
		
		int x=0, y=0;
		rep(i,1,n){
			if(col[i]==1) x++;
			else if(col[i]==2) y++;
		}
		cout<<1LL*(x-1)*(y-1)<<endl;
	}	
    return 0;
}

F

看起来挺恶心的题,待补,想看的可以评论区踢我
https://codeforces.com/contest/1277/problem/F

上一篇:codeforces round 742D


下一篇:js基础---Math工具类