Codeforces Round #435 (Div. 2) A-C题解+D代码

传送门:点击打开链接

A. Mahmoud and Ehab and the MEX
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Dr. Evil kidnapped Mahmoud and Ehab in the evil land because of their performance in the Evil Olympiad in Informatics (EOI). He decided to give them some problems to let them go.

Dr. Evil is interested in sets, He has a set of n integers. Dr. Evil calls a set of integers evil if the MEX of it is exactly x. the MEX of a set of integers is the minimum non-negative integer that doesn't exist in it. For example, the MEX of the set {0, 2, 4} is 1 and the MEX of the set {1, 2, 3} is 0 .

Dr. Evil is going to make his set evil. To do this he can perform some operations. During each operation he can add some non-negative integer to his set or erase some element from it. What is the minimal number of operations Dr. Evil has to perform to make his set evil?

Input

The first line contains two integers n and x (1 ≤ n ≤ 1000 ≤ x ≤ 100) — the size of the set Dr. Evil owns, and the desired MEX.

The second line contains n distinct non-negative integers not exceeding 100 that represent the set.

Output

The only line should contain one integer — the minimal number of operations Dr. Evil should perform.

Examples
input
5 3
0 4 5 6 7
output
2
input
1 0
0
output
1
input
5 0
1 2 3 4 5
output
0
Note

For the first test case Dr. Evil should add 1 and 2 to the set performing 2 operations.

For the second test case Dr. Evil should erase 0 from the set. After that, the set becomes empty, so the MEX of it is 0.

In the third test case the set is already evil.


好难懂的俄式英语,还是没看明白题目说的什么。就是让求出前K个数中缺少的数的个数,如果k存在数列中,则结果加1.  水的可以的题。

代码实现:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<cstdio>
#define ll long long
#define mset(a,x) memset(a,x,sizeof(a))
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;
const double PI=acos(-1);
const int inf=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e6+5;
const int mod=1e9+7;
int dir[4][2]={0,1,1,0,0,-1,-1,0};

int main()
{
	int visit[105],x,n,i,y,maxx;
	while(cin>>n>>x)
	{
		mset(visit,0);
		maxx=0;
		for(i=0;i<n;i++)
		{
			cin>>y;
			visit[y]=1;
		}
		int ans=0;
		for(i=0;i<=x-1;i++)
		{
			if(!visit[i]&&i!=x)
			ans++;
		}
		if(visit[x])
		ans++;
		cout<<ans<<endl;
	}
	return 0;
}

B. Mahmoud and Ehab and the bipartiteness
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Mahmoud and Ehab continue their adventures! As everybody in the evil land knows, Dr. Evil likes bipartite graphs, especially trees.

A tree is a connected acyclic graph. A bipartite graph is a graph, whose vertices can be partitioned into 2 sets in such a way, that for each edge (u, v) that belongs to the graph, u and v belong to different sets. You can find more formal definitions of a tree and a bipartite graph in the notes section below.

Dr. Evil gave Mahmoud and Ehab a tree consisting of n nodes and asked them to add edges to it in such a way, that the graph is still bipartite. Besides, after adding these edges the graph should be simple (doesn't contain loops or multiple edges). What is the maximum number of edges they can add?

A loop is an edge, which connects a node with itself. Graph doesn't contain multiple edges when for each pair of nodes there is no more than one edge between them. A cycle and a loop aren't the same .

Input

The first line of input contains an integer n — the number of nodes in the tree (1 ≤ n ≤ 105).

The next n - 1 lines contain integers u and v (1 ≤ u, v ≤ nu ≠ v) — the description of the edges of the tree.

It's guaranteed that the given graph is a tree.

Output

Output one integer — the maximum number of edges that Mahmoud and Ehab can add to the tree while fulfilling the conditions.

Examples
input
3
1 2
1 3
output
0
input
5
1 2
2 3
3 4
4 5
output
2
Note

Tree definition: https://en.wikipedia.org/wiki/Tree_(graph_theory)

Bipartite graph definition: https://en.wikipedia.org/wiki/Bipartite_graph

In the first test case the only edge that can be added in such a way, that graph won't contain loops or multiple edges is (2, 3), but adding this edge will make the graph non-bipartite so the answer is 0.

In the second test case Mahmoud and Ehab can add edges (1, 4) and (2, 5).


这个题蛮可以的,给你N个点,N-1条边,问在满足条件的前提下,最多可以添加几条边。
需要满足的条件就是将N个点分成两组,每组中的点彼此之间都不能有连线。

可以自己画一个图看看,最后的结果是分成两组点,两个组里的点跟对面的点之间都有连线。
首先,这是一棵树,然后可以发现每隔一个点都可以不相连,这样的话DFS的参数中加一个步数,用步数模除2,求出奇数步跟偶数步,这样的两组点就是符合题目要求的点,然后彼此连线,需要sum1(奇数点个数)*sum2(偶数点个数)条边,最后减去n-1得到结果。
注意要用vector,将输入的两个点一个点做下标,另一个点做权值。

带权值的并查集也可以做这个题。

代码实现:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#define ll long long
#define mset(a,x) memset(a,x,sizeof(a))
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;
const double PI=acos(-1);
const int inf=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e5+5;
const int mod=1e9+7;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
vector <int> Vec[maxn];
int visit[maxn];
ll sum1,sum2;

void dfs(int x,int step)
{
	for(int i=0;i<Vec[x].size();i++)
	{
		if(!visit[Vec[x][i]])
		{
			visit[Vec[x][i]]=1;
			if(step%2)
			sum1++;
			else
			sum2++;
			dfs(Vec[x][i],step+1);
		}
	}
}

int main()
{
	int i,x,y,n;
	while(cin>>n)
	{
		for(i=0;i<maxn;i++)
		Vec[i].clear();
		mset(visit,0);
		for(i=0;i<n-1;i++)
		{
			cin>>x>>y;
			Vec[x].push_back(y);
			Vec[y].push_back(x);
		}
		
		sum1=1;sum2=0;
		visit[1]=1;
		dfs(1,0);
		cout<<sum1*sum2-(n-1)<<endl;
	}
	return 0;
}


C. Mahmoud and Ehab and the xor
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Mahmoud and Ehab are on the third stage of their adventures now. As you know, Dr. Evil likes sets. This time he won't show them any set from his large collection, but will ask them to create a new set to replenish his beautiful collection of sets.

Dr. Evil has his favorite evil integer x. He asks Mahmoud and Ehab to find a set of n distinct non-negative integers such the bitwise-xor sum of the integers in it is exactly x. Dr. Evil doesn't like big numbers, so any number in the set shouldn't be greater than 106.

Input

The only line contains two integers n and x (1 ≤ n ≤ 1050 ≤ x ≤ 105) — the number of elements in the set and the desired bitwise-xor, respectively.

Output

If there is no such set, print "NO" (without quotes).

Otherwise, on the first line print "YES" (without quotes) and on the second line print n distinct integers, denoting the elements in the set is any order. If there are multiple solutions you can print any of them.

Examples
input
5 5
output
YES
1 2 4 5 7
input
3 6
output
YES
1 2 5
Note

You can read more about the bitwise-xor operation here: https://en.wikipedia.org/wiki/Bitwise_operation#XOR

For the first sample .

For the second sample .

输出n个数,使这些数异或的和等于k。

每一个数异或两遍就会得到0,这样可以输出前n-1个数,让最后那个数去异或每一个数,得到的数可能跟前面的数相等,所以要判断一下,另外,当n==1,直接输出k就可以,当n==2且k==0时,没有结果。

代码实现:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#define ll long long
#define mset(a,x) memset(a,x,sizeof(a))
#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;
const double PI=acos(-1);
const int inf=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e5+5;
const int mod=1e9+7;
int dir[4][2]={0,1,1,0,0,-1,-1,0};
int ans[maxn];

int main()
{
	int i,j,k,n;
	while(cin>>n>>k)
	{
		if(n==1)
		{
			cout<<"YES"<<endl;
			cout<<k<<endl;
			continue;
		}
		
		if(n==2&&!k)
		{
			cout<<"NO"<<endl;
			continue;
		}
		
		ans[n-1]=k;
		for(i=0;i<n-1;i++)
		{
			ans[i]=i;
			ans[n-1]^=i;
		}
		
		if(ans[n-1]<n-1)
		{
			if(ans[n-1]!=ans[n-2])
			ans[n-2]^=(1<<18);
			else
			ans[n-3]^=(1<<18);
			
			ans[n-1]^=(1<<18);
		}
		cout<<"YES"<<endl;
		for(i=0;i<n;i++)
		cout<<ans[i]<<' ';
		
		cout<<endl;
	}
	return 0;
}

D. Mahmoud and Ehab and the binary string
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Mahmoud and Ehab are in the fourth stage now.

Dr. Evil has a hidden binary string of length n. He guarantees that there is at least one '0' symbol and at least one '1' symbol in it. Now he wants Mahmoud and Ehab to find a position of any '0' symbol and any '1' symbol. In order to do this, Mahmoud and Ehab can ask Dr. Evil up to 15 questions. They tell Dr. Evil some binary string of length n, and Dr. Evil tells the Hamming distance between these two strings. Hamming distance between 2 binary strings of the same length is the number of positions in which they have different symbols. You can find the definition of Hamming distance in the notes section below.

Help Mahmoud and Ehab find these two positions.

You will get Wrong Answer verdict if

  • Your queries doesn't satisfy interaction protocol described below.
  • You ask strictly more than 15 questions and your program terminated after exceeding queries limit. Please note, that you can do up to 15 ask queries and one answer query.
  • Your final answer is not correct.
You will get  Idleness Limit Exceeded if you don't print anything or if you forget to flush the output, including for the final answer (more info about flushing output below).

If you exceed the maximum number of queries, You should terminate with 0, In this case you'll get Wrong Answer, If you don't terminate you may receive any verdict because you'll be reading from a closed stream .

Input

The first line of input will contain a single integer n (2 ≤ n ≤ 1000) — the length of the hidden binary string.

Output

To print the final answer, print "! pos0 pos1" (without quotes), where pos0 and pos1 are positions of some '0' and some '1' in the string (the string is 1-indexed). Don't forget to flush the output after printing the answer!

Interaction

To ask a question use the format "? s" (without quotes), where s is a query string. Don't forget to flush the output after printing a query!

After each query you can read a single integer from standard input — the Hamming distance between the hidden string and the query string.

To flush the output you can use:-

  • fflush(stdout) in C++;
  • System.out.flush() in Java;
  • stdout.flush() in Python;
  • flush(output) in Pascal;
  • See the documentation for other languages .

Hacking.

To hack someone just print one binary string with length up to 1000, containing at least one '0' and at least one '1'.

Example
input
3
2
1
3
2
1
0
output
? 000
? 001
? 010
? 011
? 100
? 101
! 2 1
Note

Hamming distance definition: https://en.wikipedia.org/wiki/Hamming_distance

In the first test case the hidden binary string is 101, The first query is 000, so the Hamming distance is 2. In the second query the hidden string is still 101 and query is 001, so the Hamming distance is 1.

After some queries you find that symbol at position 2 is '0' and symbol at position 1 is '1', so you print "! 2 1".


代码实现:

#include<bits/stdc++.h>
using namespace std;

int n,p0,p1,v;

int ask(string s)
{
    printf("? ");
    for(int i=0;i<s.length();i++)printf("%c",s[i]);
    printf("\n");fflush(stdout);
    int x;
    scanf("%d",&x);
    return x;
}

int main()
{
    scanf("%d",&n);
    string t="";
    for(int i=1;i<=n;i++)t+='1';
    int a1=ask(t);
    t="0";
    for(int i=1;i<n;i++)t+='1';
    int a2=ask(t);
    if(a1<a2)p1=1,v=0;else p0=1,v=1;
    int l=2,r=n;
    while(r-l>=1)
    {
        int mid=(l+r)>>1;
        if(v==0)
        {
            t="";
            for(int i=1;i<l;i++)t+='1';
            for(int i=l;i<=mid;i++)t+='0';
            for(int i=mid+1;i<=n;i++)t+='1';
            int now=ask(t);
            if(now-a1>=mid-l+1)l=mid+1;else r=mid;
        }else
        {
            t="";
            for(int i=1;i<l;i++)t+='1';
            for(int i=l;i<=mid;i++)t+='0';
            for(int i=mid+1;i<=n;i++)t+='1';
            int now=ask(t);
            if(a1-now>=mid-l+1)l=mid+1;else r=mid;
        }
    }
    if(p0==0)p0=l;else p1=l;
    printf("! %d %d\n",p0,p1);
    fflush(stdout);
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值