Codeforces Round #738 (Div. 2)

这场真是手速场,掉分了hhhh;

A:只有1 & 1操作才会出现1,操作又可以进行无限次,那么要出现最小值,那么必然是要所有都进行一次。

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define pb push_back
#define pi pair<int,int> 
#define fi first
#define se second
using namespace std;
typedef long long ll;
const ll maxn=1e5+10;
#define int ll
inline int read()
{
    char ch = getchar();
    int x = 0, f = 1;
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
int a[maxn];
signed main()
{
    ios::sync_with_stdio(false);
    int t;
    cin >> t;
    while (t--)
    {
        int n,m;
        cin >> n;
        for (int i = 1; i<= n;i++)
        {
            cin >> a[i];
        }
        int ans = a[1];
        for (int i = 2;i <=n;i++)
        {
          ans &= a[i];
        }
        cout << ans << '\n';
    }
}

B:给你一个字符串,要求相邻出现的字符尽量不相同。

自然是形如RB相邻最少,找到第一个非问号向两边拓展就可。

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define pb push_back
#define pi pair<int,int> 
#define fi first
#define se second
using namespace std;
typedef long long ll;
const ll maxn=1e5+10;
#define int ll
inline int read()
{
    char ch = getchar();
    int x = 0, f = 1;
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
signed main()
{
    ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--)
    {  
        int n ;
        cin>>n;
        string s;
        cin>>s;
        int now = 0;
        for(int i=n-1 ; i>=0 ; i--)
        {
            if(s[i]!='?')
            {
                now = i;
                break;
            }
        }
        for(int i=now ; i<n ; ++i)
        {
            if(s[i]=='?')
            {
                if(s[i-1]=='R') s[i]='B';
                else s[i]='R';
            }
        }  
        for(int i=now ; i>=0 ; --i)
        {
            if(s[i]=='?')
            {
                if(s[i+1]=='R') s[i]='B';
                else s[i] = 'R';
            }
        } 
        cout<<s<<endl;
    }
}

C:给n+1个点,n个数,0代表从i到n+1的一条有向边,1代表从n+1到i的边。能否从一个点开始走完全程。

3个情况,n+1有到1的边,n有到n+1的边,或者相邻的0 ,1 ;

#include <bits/stdc++.h>
constexpr int N = 2e5+10;
using namespace std;
int a[N];
int main()
{
    int t;
    cin >> t;
    while (t--)
    {
        int n;
        cin >> n;
        for (int i = 1;i <= n;i++) cin >> a[i];
        if (a[n] == 0)
        {
            for (int i = 1;i <= n+1;i++) cout << i << " ";
            cout << endl;
        }
        else if (a[1] == 1)
        {
            cout << n+1 << " ";
            for (int i = 1;i <= n;i++) cout << i << " ";
            cout << endl;
        }
        else
        {
            int k = -1;
            for (int i = 1;i <= n-1;i++)
            {
                if (a[i] == 0 && a[i+1] == 1)
                {
                    k = i+1;
                    break;
                }
            }
            if (k == -1) cout << -1;
            else  for (int i = 1;i <= n;i++)
            {
                if (i == k) cout << n+1 << " " << i << " ";
                else cout << i << " ";
            }
            cout << endl;
        }
    }
}

D1&& D2 

D2 后来没写出来。。。

给你两个结点相同的图,如果能加相同的边,并且还是森林,那么对答案贡献+1,问最多有几条边。输出它们。

那么思想当然是并查集。如果都满足那么直接加边。

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define pb push_back
#define pi pair<int,int> 
#define fi first
#define se second
using namespace std;
typedef long long ll;
const ll maxn=1e5+10;
#define int ll
inline int read()
{
    char ch = getchar();
    int x = 0, f = 1;
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
int n,m,f1[maxn];
int f2[maxn];
void init(void)
{
    for (int i = 1;i <= n;i++)
    f1[i] = i,f2[i] = i;
}
int find1(int x)
{
    if(f1[x]!=x) f1[x]=find1(f1[x]);
    return f1[x];
}
int find2 (int x)
{
     if(f2[x]!=x) f2[x]=find2(f2[x]);
    return f2[x];
}
signed main()
{
    ios::sync_with_stdio(false);
    int m1,m2;
    cin >> n >> m1 >> m2;
    init();
    for (int i = 1;i <= m1;i++)
    {
        int  u,v;
        u = read();
        v = read();
        if (find1(u) != find1 (v))
        {
            f1[find1 (u)] = find1 (v) ;
        }
        }
        for (int i = 1;i <= m2;i++)
        {
            int u,v;
            u = read();
            v = read();
             if (find2(u) != find2 (v))
            {
                f2[find2 (u)] = find2 (v) ;
            }
        }
        vector <pi> ans;
        for (int i = 1;i <= n;i++)
        {
            for (int j = i+1;j <=n;j++)
            {
               if ((find1(i) != find1(j)) && (find2(i) != find2(j)))
               {
                   ans.push_back({i,j});
                   f1[find1(i)] = find1(j);
                   f2[find2(i)] = find2(j);
               }
            }
        }
        cout<<(int)ans.size()<<'\n';
        for(auto w:ans)
        {
        cout<<w.fi<<' '<<w.se<<'\n';
        }
}

d2对数据的范围加大了,显然不能遍历所有的边了。有一种巧妙的办法。(见代码)

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define pb push_back
#define pi pair<int,int> 
#define fi first
#define se second
using namespace std;
typedef long long ll;
const ll maxn=1e5+10;
#define int ll
int read()
{
    char ch = getchar();
    int x = 0, f = 1;
    while(ch < '0' || ch > '9')
    {
        if(ch == '-') f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9')
    {
        x = (x<<2)+(x<<3) + ch - '0';
        ch = getchar();
    }
    if(f) return x;
    return ~(x-1);
}
int n,m,f1[maxn];
int f2[maxn];
void init(void)
{
    for (int i = 1;i <= n;i++)
    f1[i] = i,f2[i] = i;
}
int find1(int x)
{
    if(f1[x]!=x) f1[x]=find1(f1[x]);
    return f1[x];
}
int find2 (int x)
{
     if(f2[x]!=x) f2[x]=find2(f2[x]);
    return f2[x];
}
void check1(int x,int y)
{
    if (find1(x) != find1 (y))
    {
        f1[find1 (x)] = find1 (y);
        return ;
    }
    else return ;
}
void check2(int x,int y)
{
    if (find2(x) != find2 (y))
    {
        f2[find2 (x)] = find2 (y);
        return ;
    }
    else return ;
}
int vis[maxn];
bool ok1 (int x,int y)
{
    if (find1(x) == find1(y)) return false;
    return true;
}
bool ok2 (int x,int y)
{
    if (find2(x) == find2(y)) return false;
    return true;
}
signed main()
{
    ios::sync_with_stdio(false);
    int m1,m2;
    cin >> n >> m1 >> m2;
    init();
    for (int i = 1;i <= m1;i++)
    {
        int  u,v;
       cin >> u>> v;
        check1 (u,v);
        }
        for (int i = 1;i <= m2;i++)
        {
            int u,v;
           cin >> u>> v;
            check2(u,v);
        }
        vector <pi> ans;
        for (int i = 1;i <=n;i++)
        {
            if (ok1(1,i) && ok2(1,i))
            {
                check1(1,i);
                check2(1,i);
                ans.push_back(pi(1,i));
            }
        }
        for (int i = 1;i <= n;i++) 
        {
            if (ok1(1,i)) 
            vis[find1(i)] = 1;
        }
        vector<int>v;
        for(int i=1;i<=n;i++) 
        if(vis[i]) 
        v.push_back(i);
            for(int i=1;i<=n;i++) 
            if(ok2(1,i)&&!v.empty())
        {
        int x=v.back();
        if(ok1(i,x)&&ok2(i,x))
        {
            check1(i,x);check2(i,x);
            ans.push_back(pi(i,x));
            v.pop_back();
        }
        }
        cout<<(int)ans.size()<<'\n';
        for(auto w:ans)
        {
        cout<<w.fi<<' '<<w.se<<'\n';
        }
}

 

posted @ 2021-08-16 15:43  iAzul  阅读(32)  评论(0)    收藏  举报