传送门: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
显然是最佳的,这样可以同时干掉 two
和 one
,而对于后者我们直接选择去掉 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