Codeforces Round #606 (Div. 2)
题库链接
https://codeforces.com/contest/1277
A. Happy Birthday, Polycarp!
1-n之间有多少个美丽数(如果正整数只包含一个或多个重复一次的数字)(1,11,777...)
签到
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 200100;
const int M = 1e9+7;
ll n,t;
int dfs(int i)
{
int res = 0;
ll temp = i;
while (temp <= n)
{
res++;
temp = temp*10+i;
}
return res;
}
int solve(int k)
{
int ans = 0;
for(int i = 1; i <= 9; i++)
{
ans += dfs(i);
}
return ans;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
#endif
cin>>t;
while (t--)
{
cin>>n;
cout<<solve(n)<<endl;
}
return 0;
}
B. Make Them Odd
n个数的数组,每次可以选择一个数字(不是数组元素),让数组里面等于这个数字的元素除以2,求最小操作次数,让数组变成奇数数组
从最大的数开始,一直往下就好了
模拟
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 200100;
const int M = 1e9+7;
int n,t;
set<int> st;
vector<int> v;
bool cmp(int x,int y)
{
return x > y;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
#endif
cin(t);
while (t--)
{
st.clear();v.clear();
cin(n);
for(int i = 0,x; i < n; i++)
{
cin(x);
if(x%2==0)
{
if(st.count(x) == 0)
{
st.insert(x);
v.push_back(x);
}
}
}
sort(v.begin(),v.end(),cmp);
int ans = 0;
for(auto i : v)
{
ans++;
int k = i/2;
while (k%2==0 && st.count(k) == 0)
{
ans++;
k = k/2;
}
}
cout<<ans<<endl;
}
return 0;
}
C. As Simple as One and Two
给定一个字符串,删除一些字符,使得字符串里面没有子串"one","two"
对于twone,删除o,对于two,删除w,对于one,删除n
贪心
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 200100;
const int M = 1e9+7;
int n,m,k,t;
char s[maxn];
vector <int> ans;
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
#endif
cin(t);
while (t--)
{
ans.clear();mem(s,0);
cin>>s;
for(int i = 0; s[i]; i++)
{
if(s[i] == 't')
{
if(s[i+1] == 'w' && s[i+2] == 'o')
{
if(s[i+3] == 'n' && s[i+4] == 'e')
{
ans.push_back(i+3);
s[i+2] = '0';
}
else
{
ans.push_back(i+2);
}
}
}
if(s[i] == 'o')
{
if(s[i+1] == 'n' && s[i+2] == 'e')
{
ans.push_back(i+2);
}
}
}
cout<<ans.size()<<endl;
for(auto i : ans) cout<<i<<' ';
cout<<endl;
}
return 0;
}
D. Let's Play the Words?
n个不同的二进制串,组成一个大串,前一个的最后一个数字是后一个的第一个数字,某些串可以翻转
求翻转的次数,和哪些串翻转了
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 200100;
const int M = 1e9+7;
int n,m,k,t;
vector<string> s(maxn);
set<string> s01;
set<string> s10;
bool u[2];
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
#endif
cin(t);
while (t--)
{
s.clear();s01.clear();s10.clear();u[0] = u[1] = 0;
cin(n);
for(int i = 0; i < n; i++)
{
cin>>s[i];
if(s[i][0] == '0' && s[i].back() == '1') s01.insert(s[i]);
if(s[i][0] == '1' && s[i].back() == '0') s10.insert(s[i]);
u[s[i][0] - '0'] = u[s[i].back()-'0'] = 1;
}
int a = s01.size(),b = s10.size();
if(u[0] && u[1] && a == 0 && b == 0)
{
printf("-1\n");
continue;
}
vector<int> res;
if(a > b+1) //01多
{
for(int i = 0; i < n; i++)
{
if(s[i][0] == '0' && s[i].back() == '1')
{
string ss(s[i]);
reverse(ss.begin(),ss.end());
if(s10.count(ss) == 0)
{
res.push_back(i);
}
}
}
}
else if (b > a+1)
{
for(int i = 0; i < n; i++)
{
if(s[i][0] == '1' && s[i].back() == '0')
{
string ss(s[i]);
reverse(ss.begin(),ss.end());
if(s01.count(ss) == 0)
{
res.push_back(i);
}
}
}
}
int ans = abs(a-b)/2;
printf("%d\n",ans);
for(int i = 0; i < ans; i++)
{
printf("%d ",res[i]+1);
}
printf("\n");
}
return 0;
}
E. Two Fairs
给定一个无向连通图,n个顶点,m条边,a顶点,b顶点
问有多少对(x,y),x到y一定会经过a和b
由于是联通图,任意两点可达,从a出发,不经过b,进行dfs,没有访问过的点就是必须经过b的点
再从b出发,不经过a,进行dfs,没有访问过的点就是必须经过a的点
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 200100;
const int maxm = 1000100;
const int M = 1e9+7;
int n,cnt,m,a,b,t;
ll res,ans1,ans2;
int head[maxn], to[maxm], Next[maxm];
void add(int u,int v)
{
to[cnt] = v;
Next[cnt] = head[u],head[u] = cnt;
cnt++;
}
bool vis[maxn];
bool dfs(int s)
{
res++;
vis[s] = 1;
for(int i = head[s]; i != -1; i = Next[i])
{
int v = to[i];
if(!vis[v]) dfs(v);
}
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
#endif
cin(t);
while (t--)
{
cnt = 0;
mem(head,-1);
cin(n),cin(m),cin(a),cin(b);
for(int i = 0,u,v; i < m; i++)
{
cin(u),cin(v);
add(u,v),add(v,u);
}
res = 0;
mem(vis,0);vis[b] = 1;dfs(a);
ans1 = n - res - 1;
res = 0;
mem(vis,0);vis[a] = 1;dfs(b);
ans2 = n - res - 1;
printf("%lld\n",ans1*ans2);
}
return 0;
}
F. Beautiful Rectangle
给定n个数,组成完美矩阵(每一行和每一列中所有值都不同)
输出可以构造的最大矩阵(元素个数最多)
#include <bits/stdc++.h>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define cin(a) scanf("%d",&a)
#define pii pair<int,int>
#define ll long long
#define gcd __gcd
const int inf = 0x3f3f3f3f;
const int maxn = 200100;
const int M = 1e9+7;
map<int,int> cnts;
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("data.in", "r", stdin);
//freopen("data.out", "w", stdout);
#endif
int n;
scanf("%d",&n);
for(int i = 0,x; i < n; i++)
{
cin(x);
cnts[x]++;
}
vector<vector<int>> val_by_cnt(n+1); //出现次数
for(auto val_cnt : cnts)
{
val_by_cnt[val_cnt.second].push_back(val_cnt.first);
}
int gep[n+1];
gep[n] = val_by_cnt[n].size();
for(int i = n-1; i >= -1; i--)
{
gep[i] = gep[i+1] + val_by_cnt[i].size();
}
int tot = 0,best = 0,best_a,best_b;
for(int a = 1; a <= n; a++)
{
tot += gep[a]; //一个数最多出现a次,所以有a行答案
int b = tot/a; //b列
if(a <= b && best < a*b) //求a行b列的最大值咯
{
best = a*b;
best_a = a;
best_b = b;
}
}
cout<<best<<endl<<best_a<<' '<<best_b<<endl;
vector<vector<int>> r(best_a,vector<int>(best_b));
int x = 0, y = 0; //开始填答案
for(int i = n; i >= 1; i--)
{
for(auto val : val_by_cnt[i])
{
for(int j = 0; j < min(i,best_a); j++)
{
if(r[x][y] != 0)
{
x = (x+1)%best_a;
}
if(r[x][y] == 0)
{
r[x][y] = val;
}
x = (x+1)%best_a;
y = (y+1)%best_b;
}
}
}
for(int i = 0; i < best_a; i++)
{
for(int j = 0; j < best_b; j++)
cout<<r[i][j]<<' ';
cout<<endl;
}
return 0;
}