/*
C:
题意:给出一个整数数列,最大值最小值相差不超过2,
要求构造一个新的等长数列,使得(跟原来的数列相同的
数字最少)并且(两数列的和相等)并且(新数列的最大
值小于等于原数列的最大值,新数列的最小值大于等于原
数列的最小值)
题意:给出一个整数数列,最大值最小值相差不超过2,
要求构造一个新的等长数列,使得(跟原来的数列相同的
数字最少)并且(两数列的和相等)并且(新数列的最大
值小于等于原数列的最大值,新数列的最小值大于等于原
数列的最小值)
思路:题目关键在于原来的数列最大值与最小值相差不超
过2,当相差为1或者0的时候,无法改变原数列数字的大小;
当相差为2时,可以将中间的数向两边转化,或者两边的数
向中间转化;
*/
过2,当相差为1或者0的时候,无法改变原数列数字的大小;
当相差为2时,可以将中间的数向两边转化,或者两边的数
向中间转化;
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200010;
int cnt[maxn];
int a[maxn];
int main()
{
memset(cnt,0,sizeof(cnt));
int n;
int ma = -maxn,mi = maxn;
scanf("%d",&n);
for(int i = 0; i < n; i++)
{
int x;
scanf("%d",&x);
a[i] = x + 100000;
if(a[i] > ma)
ma = a[i];
if(a[i] < mi)
mi = a[i];
cnt[a[i]]++;
}
//printf("%d %d\n",mi,ma);
if(mi == ma || ma-mi == 1)
{
//cout<<1<<endl;
printf("%d\n",n);
for(int i = 0; i < n-1; i++)
printf("%d ",a[i]-100000);
printf("%d\n",a[n-1]-100000);
}
else
{
int tmp = ma - 100000;
int a = cnt[ma];
int b = cnt[ma-1];
int c = cnt[mi];
int m;
//printf("%d %d %d\n",a,b,c);
mi = min(a,c);
if(mi*2 >= b/2*2)
{
m = n - (mi*2);
a -= mi;
c -= mi;
b += mi*2;
}
else
{
m = n - (b/2*2);
a += b/2;
c += b/2;
b -= b/2*2;
}
//printf("%d %d %d\n",a,b,c);
printf("%d\n",m);
for(int i = 0; i < a; i++)
printf("%d ",tmp);
for(int i = 0; i < b-1; i++)
printf("%d ",tmp-1);
if(c == 0)
printf("%d\n",tmp-1);
else if(b != 0)
printf("%d ",tmp-1);
for(int i = 0; i < c-1; i++)
printf("%d ",tmp-2);
if(c > 0)
printf("%d\n",tmp-2);
}
return 0;
}
using namespace std;
const int maxn = 200010;
int cnt[maxn];
int a[maxn];
int main()
{
memset(cnt,0,sizeof(cnt));
int n;
int ma = -maxn,mi = maxn;
scanf("%d",&n);
for(int i = 0; i < n; i++)
{
int x;
scanf("%d",&x);
a[i] = x + 100000;
if(a[i] > ma)
ma = a[i];
if(a[i] < mi)
mi = a[i];
cnt[a[i]]++;
}
//printf("%d %d\n",mi,ma);
if(mi == ma || ma-mi == 1)
{
//cout<<1<<endl;
printf("%d\n",n);
for(int i = 0; i < n-1; i++)
printf("%d ",a[i]-100000);
printf("%d\n",a[n-1]-100000);
}
else
{
int tmp = ma - 100000;
int a = cnt[ma];
int b = cnt[ma-1];
int c = cnt[mi];
int m;
//printf("%d %d %d\n",a,b,c);
mi = min(a,c);
if(mi*2 >= b/2*2)
{
m = n - (mi*2);
a -= mi;
c -= mi;
b += mi*2;
}
else
{
m = n - (b/2*2);
a += b/2;
c += b/2;
b -= b/2*2;
}
//printf("%d %d %d\n",a,b,c);
printf("%d\n",m);
for(int i = 0; i < a; i++)
printf("%d ",tmp);
for(int i = 0; i < b-1; i++)
printf("%d ",tmp-1);
if(c == 0)
printf("%d\n",tmp-1);
else if(b != 0)
printf("%d ",tmp-1);
for(int i = 0; i < c-1; i++)
printf("%d ",tmp-2);
if(c > 0)
printf("%d\n",tmp-2);
}
return 0;
}
/*
D:
题意:有一颗苹果树,一旦树开始结果,每个节点中就会出现
一个苹果,并且沿着树枝向树底滚下去。除了第一花序中的苹
果之外,所有的苹果每秒钟同时向下滚动一个分枝,一旦有两
个苹果在同一个节点相遇,则两个苹果就会抵消(即每层最后
只会剩下0个或者1个苹果),求最终能的到苹果的总量。
D:
题意:有一颗苹果树,一旦树开始结果,每个节点中就会出现
一个苹果,并且沿着树枝向树底滚下去。除了第一花序中的苹
果之外,所有的苹果每秒钟同时向下滚动一个分枝,一旦有两
个苹果在同一个节点相遇,则两个苹果就会抵消(即每层最后
只会剩下0个或者1个苹果),求最终能的到苹果的总量。
思路:dfs统计每层苹果数量,是奇数则这层将会得到一个苹果,
偶数不能得到苹果
*/
#include<bits/stdc++.h>
using namespace std;
int cnt[100100];
bool vis[100100];
vector<int> g[100100];
int n;
void dfs(int x,int step)
{
vis[x] = 1;
cnt[step]++;
for(int i = 0; i < g[x].size(); i++)
{
if(!vis[g[x][i]])
dfs(g[x][i],step+1);
}
}
int main()
{
scanf("%d",&n);
memset(cnt,0,sizeof(cnt));
memset(vis,0,sizeof(vis));
for(int i = 2; i <= n; i++)
{
int x;
scanf("%d",&x);
g[x].push_back(i);
}
dfs(1,1);
int sum = 0;
for(int i = 1; i <= n; i++)
if(cnt[i]%2 != 0)
sum++;
printf("%d\n",sum);
return 0;
}
偶数不能得到苹果
*/
#include<bits/stdc++.h>
using namespace std;
int cnt[100100];
bool vis[100100];
vector<int> g[100100];
int n;
void dfs(int x,int step)
{
vis[x] = 1;
cnt[step]++;
for(int i = 0; i < g[x].size(); i++)
{
if(!vis[g[x][i]])
dfs(g[x][i],step+1);
}
}
int main()
{
scanf("%d",&n);
memset(cnt,0,sizeof(cnt));
memset(vis,0,sizeof(vis));
for(int i = 2; i <= n; i++)
{
int x;
scanf("%d",&x);
g[x].push_back(i);
}
dfs(1,1);
int sum = 0;
for(int i = 1; i <= n; i++)
if(cnt[i]%2 != 0)
sum++;
printf("%d\n",sum);
return 0;
}