Codeforces Round #500 (Div. 2) [based on EJOI] A B C D(思维 数学)

12 篇文章 0 订阅
1 篇文章 0 订阅

A:判断sum大小即可 (从a序列变成b序列,每个位置只能移走,或者交换) code略

B:n个数,和一个x,现在有一个操作,a_i不变,或者变为a_i & x,问你最少几个操作可以使得a_i == a_i && i != j

显然只有0,1,2,-1这几种答案 (我写的比较麻烦了,其实就是模拟判断一下)

int a[maxn];
int b[maxn];
string s[maxn];
int cnt[maxn];
map<int,int>m;
int main() {
    ios::sync_with_stdio(false);
    int x;
    while(cin >> n >> x){
        for(int i = 1;i <= n;i++) cin >> a[i],m[a[i]]++;
        for(auto d:m){
            if(d.se >= 2){
                cout << 0 << endl;
                return 0;
            }
        }
        m.clear();
        m[x]++;
        string str = "";
        int flag = 0;
        for(int i = 1;i <= n;i++)
            if(m[a[i]])
                flag = 1;
        map<int,int>mp;
        if(flag){
            for(int i = 1;i <= n;i++){
                if(m[a[i]]) continue;
                mp[a[i] & x]++;
                if(x == a[i] & x && mp[a[i] & x] ){
                    cout << 1 << endl;
                    return 0;
                }
            }
        }
            mp.clear();
            map<P,int>mp1;
            m.clear();
            for(int i = 1;i <= n;i++)mp1[P(a[i],i)]++;
            for(int i = 1;i <= n;i++)m[a[i]]++;
            for(int i = 1;i <= n;i++){
                mp[a[i] & x]++;
                if(m[a[i] & x] && mp1[P(a[i] & x,i)] == 0)
                {
                     cout << 1 << endl;
                     return 0;
                }
            }
            for(auto d:mp){
                if(d.se >= 2){
                    cout << 2 << endl;
                    return 0;
                }
            }
            cout << -1 << endl;
    }
}

C:2 * n个数,生成n个坐标,要求矩形可以包括这n个坐标,让矩形面积最小。

数学题,两种情况一种max和min在一组的时候,这是一个边,那另外一个边应该尽量小,所以就是遍历一下求一下差,

另外一种从中间分开,计算一下求个min


ll a[maxn];
ll d[maxn];
map<int,int>m;
int main() {
    ios::sync_with_stdio(false);
    int x;
    while(cin >> n){
        for(int i = 1;i <= n * 2;i++) cin >> a[i];
        for(auto d:m)  if(d.se >= n) return cout << 0 << endl,0;
        int id = 0,Max = 0;
        sort(a + 1,a + 1 + 2 * n);
        ll ans = 0;
        ll P1 = a[2 * n] - a[1],P2 = INFL;
        deque<int>dq;
        for(int i = 2;i < 2 * n;i++)   {
            if(i >=  n + 1)
//            cout << i << " " <<  i - n << endl;
            P2 = min(P2,a[i] - a[i - n + 1]);
        }
        //        debug();
//        cout << P1 * P2 << endl;
        ans = min(P1 * P2,(a[n] - a[1]) * (a[n * 2] - a[n + 1]));
        cout << ans << endl;

    }
}

D:思维好题

D. Chemical table

time limit per test

1 second

memory limit per test

512 megabytes

input

standard input

output

standard output

Innopolis University scientists continue to investigate the periodic table. There are n·m known elements and they form a periodic table: a rectangle with n rows and m columns. Each element can be described by its coordinates (r, c) (1 ≤ r ≤ n, 1 ≤ c ≤ m) in the table.

Recently scientists discovered that for every four different elements in this table that form a rectangle with sides parallel to the sides of the table, if they have samples of three of the four elements, they can produce a sample of the fourth element using nuclear fusion. So if we have elements in positions (r1, c1), (r1, c2), (r2, c1), where r1 ≠ r2 and c1 ≠ c2, then we can produce element (r2, c2).

Samples used in fusion are not wasted and can be used again in future fusions. Newly crafted elements also can be used in future fusions.

Innopolis University scientists already have samples of q elements. They want to obtain samples of all n·m elements. To achieve that, they will purchase some samples from other laboratories and then produce all remaining elements using an arbitrary number of nuclear fusions in some order. Help them to find the minimal number of elements they need to purchase.

Input

The first line contains three integers nmq (1 ≤ n, m ≤ 200 000; 0 ≤ q ≤ min(n·m, 200 000)), the chemical table dimensions and the number of elements scientists already have.

The following q lines contain two integers rici (1 ≤ ri ≤ n, 1 ≤ ci ≤ m), each describes an element that scientists already have. All elements in the input are different.

Output

Print the minimal number of elements to be purchased.

Examples

input

Copy

2 2 3
1 2
2 2
2 1

output

Copy

0

input

Copy

1 5 3
1 3
1 1
1 5

output

Copy

2

input

Copy

4 3 6
1 2
1 3
2 2
2 3
3 1
3 3

output

Copy

1

Note

For each example you have a picture which illustrates it.

The first picture for each example describes the initial set of element samples available. Black crosses represent elements available in the lab initially.

The second picture describes how remaining samples can be obtained. Red dashed circles denote elements that should be purchased from other labs (the optimal solution should minimize the number of red circles). Blue dashed circles are elements that can be produced with nuclear fusion. They are numbered in order in which they can be produced.

Test 1

We can use nuclear fusion and get the element from three other samples, so we don't need to purchase anything.

Test 2

We cannot use any nuclear fusion at all as there is only one row, so we have to purchase all missing elements.

Test 3

There are several possible solutions. One of them is illustrated below.

Note that after purchasing one element marked as red it's still not possible to immidiately produce the middle element in the bottom row (marked as 4). So we produce the element in the left-top corner first (marked as 1), and then use it in future fusions.

 

判断连通,对于每个加入的点,建一个x 和 y + n的边,然后跑一下dfs就可以了

ll n,k,m,q;
vector<int>v[maxn];
int vis[maxn];
void dfs(int x){
    vis[x] = 1;
    for(auto d:v[x]){
        if(!vis[d])
        dfs(d);
    }
    return ;
}
int main() {
    ios::sync_with_stdio(false);
    while(cin >> n >> m >> q){
        while(q--){
            int x,y; 
            cin >> x >> y;
            v[x].push_back(y + n);
            v[y + n].push_back(x);
        }
        ll ans = 0;
        for(int i = 1;i <= n + m;i++)  if(!vis[i])  dfs(i),ans++;
        cout << ans - 1 << endl;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值