A:
1.没有奇数肯定不行
2.有奇数无偶数,判断x是否奇数
3.有奇数有偶数,判断x是否等于n,
等于n则判断奇数个数是否是奇数
否则一定可以(可以通过改变加奇数个数来改变奇偶性,因为至少一个偶数)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
int a[M];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--)
{
int n,x;
cin>>n>>x;
int o=0,e=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]&1)o++;
else e++;
}
if(o)
{
if(e)
{
if(x==n)
{
if(o&1)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
else cout<<"YES"<<endl;
}
else
{
if(x&1)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
}
else cout<<"NO"<<endl;
}
return 0;
}
B:
显然只有 000111 ,111000的形式 暴力枚举即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e5+7;
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
char s[1100];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--)
{
cin>>s;
int n=strlen(s);
int mi=10000;
for(int i=0;i<=n;i++)
{
int ans=0;
for(int j=0;j<i;j++)if(s[j]=='1')ans++;
for(int j=i;j<n;j++)if(s[j]=='0')ans++;
mi=min(ans,mi);
ans =0;
for(int j=0;j<i;j++)if(s[j]=='0')ans++;
for(int j=i;j<n;j++)if(s[j]=='1')ans++;
mi=min(ans,mi);
}
cout<<mi<<endl;
}
return 0;
}
C:
当x是叶子节点时先手必胜,n==1时,x一定是叶子节点。
否则,双方都不愿意把x的度数变为1,都会尽量删去其他边。这样就只需要考虑边数的奇偶性即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 1e3+7;
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
int du[M];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--)
{
memset(du,0,sizeof(du));
int n,x;
cin>>n>>x;
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
du[u]++;
du[v]++;
}
bool f=true;//先手是否赢
if(du[x]==1||n==1)f=true;
else
{
if((n-1)&1)f=true;
else f=false;
}
// cout<<(n-1)<<" "<<f<<endl;
if(!f)cout<<"Ashish"<<endl;
else cout<<"Ayush"<<endl;
}
return 0;
}
E:
显然:只有0-1(初始为0,目标为1) 和1-0的个数相同,才能通过交换顺序来达到所有的目标。
考虑下图:
A表示 需要0-1,B表示1-0,C表示初始和目标都相同 。
如果A的数量等于B的数量,我们直接对1节点进行操作,至少可以保证有解。记录当前花费ans
显然ans不一定是最优解。
我们可以选择5(如果a[5]<a[1]),使得6,7节点交换。这样的结果一定小于ans。(相当于在节点1,交换了 1,2,3,5,在节点5交换了 6,7)
综上就有了如下做法:
先预处理s1[x],s2[x],表示x的子树中,A的个数/B的个数。
枚举所有节点x,判断a[x]是否小于所有x的父辈节点y的a[y],(即a[x]小于所有的a[y].)
如果节点x满足a[x]<a[y],则我们让ans-=a[x]*mia[x]*2。ans+=a[x]*min(s1[x],s2[x])*2; (mia[x]表示最小的a[y])
即,在x点对x子树中的 AB交换优于,在x的父辈点,对x子树中AB交换。
枚举完所有节点就可得出最小的ans。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls (o<<1)
#define rs (o<<1|1)
#define pb push_back
const double PI= acos(-1.0);
const int M = 2e5+7;
int head[M],cnt;
void init(){cnt=0,memset(head,0,sizeof(head));}
struct EDGE{int to,nxt,w;}ee[M*2];
void add(int x,int y,int w){ee[++cnt].nxt=head[x],ee[cnt].w=w,ee[cnt].to=y,head[x]=cnt;}
ll a[M],b[M];
ll s1[M],s2[M],mia[M];
void dfs(int x,int fa)
{
if(b[x]==1)s1[x]++;
if(b[x]==2)s2[x]++;
for(int i=head[x];i;i=ee[i].nxt)
{
int y=ee[i].to;
if(y==fa)continue;
mia[y]=min(a[y],mia[x]);
dfs(y,x);
s1[x]+=s1[y];s2[x]+=s2[y];
}
}
ll ans;
void gao(int x,int fa)
{
if(fa)
{
//cout<<x<<" "<<a[x]<<" "<<mia[fa]<<endl;
if(a[x]<mia[fa])
{
ll nm=min(s1[x],s2[x])*2;
ans-=nm*mia[fa];
ans+=nm*a[x];
}
}
for(int i=head[x];i;i=ee[i].nxt)
{
int y=ee[i].to;
if(y==fa)continue;
gao(y,x);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n,u,v;
cin>>n;
for(int i=1;i<=n;i++)
{
int x,y;
cin>>a[i]>>x>>y;
if(x==y)b[i]=0;
else if(x)b[i]=1;
else b[i]=2;
}
for(int i=1;i<n;i++)cin>>u>>v,add(u,v,1),add(v,u,1);
mia[1]=a[1];dfs(1,0);
if(s1[1]!=s2[1])
{
cout<<-1<<endl;
return 0;
}
// for(int i=1;i<=n;i++)
// cout<<i<<" "<<" "<<s1[i]<<" "<<s2[i]<<" "<<mia[i]<<endl;
ans=s1[1]*a[1]*2;
// cout<<ans<<" -- "<<endl;
gao(1,0);
cout<<ans<<endl;
return 0;
}