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;
}
posted @ 2019-12-18 22:35  hezongdnf  阅读(274)  评论(0)    收藏  举报