0
点赞
收藏
分享

微信扫一扫

Codeforces Round #646 (Div. 2)

迪莉娅1979 2022-09-26 阅读 87

A:​​http://codeforces.com/contest/1363/problem/A​​

题意:

n个数,能否从中找到x个数,使得sum为奇数

解析:

比赛时被自己弄吐了,懒得一个一个分析,索性直接暴力枚举

这破代码。。。各位不要学我啊。。。

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=1e3+10;
int a[maxn];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,x;
cin>>n>>x;
int j=0,o=0;
for(int i=1;i<=n;i++)
{
int md;
cin>>md;
if(md%2)
j++;
else
o++;
}
if(j==0)
{
cout<<"NO"<<endl;
}
else if(o==0)
{
if(x%2)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
else
{
if(x%2==0)
{
int ok=0,jj=1,oo=0;
while(jj<=j)
{
if((x-jj)<=o&&jj%2!=0)
{
ok=1;break;
}
else
{
jj++;
}
}
if(ok)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
else
{
if(j>=x)
cout<<"YES"<<endl;
else
{
int jj=1;
int ok=0;
while(jj<=j)
{
if(jj%2!=0&&(x-jj)<=o)
{
ok=1;break;
}
jj++;
}
if(ok)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
}
}
}

正经解析:

其实不合法只有这三种情况:

1:奇数数为0

2:偶数数为0,x为偶数

3:x==n,sum%2==0

x<n&&j>0&&o>0是一定可以的,一定可以凑出奇数和来

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e3+10;
int a[maxn];
int main()
{
int t;
cin>>t;
while(t--)
{
int n,x;
cin>>n>>x;
int sum=0,j=0;
for(int i=1;i<=n;i++)
{
int md;
cin>>md;
sum+=md;
if(md%2)
j++;
}
int o=n-j;
if((x==n&&sum%2==0)||(j==0)||(o==0&&x%2==0))
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
}

B:​​http://codeforces.com/contest/1363/problem/B​​

题意:

给出的串,要把它变成不含010,101的串来(非连续子串),操作是反转0/1,求最小操作数

解析:

只有四种情况合法:

全0:000000....

全1:11111111...

先全1,后全0:111111....000000.....

先全0,后全1:00000.....111111......

数据很小,所以可以暴力枚举每一种情况:156ms

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=1e3+10;
int a[maxn];
int main()
{
int t;
cin>>t;
while(t--)
{
string s;
cin>>s;
int len=s.length();
if(len==1||len==2)
{
cout<<"0"<<endl;continue;
}
int cnt=0;
for(int i=1;i<len;i++)
{
if(s[i]!=s[i-1])
cnt++;
}
int cnt1=0,cnt0=0;
for(int i=0;i<len;i++)
{
if(s[i]=='1')
cnt1++;
else
cnt0++;
}
if(cnt==1||cnt==0||cnt1==0||cnt0==0)
{
cout<<"0"<<endl;continue;
}
int minn=min(cnt1,cnt0);//00110
for(int i=0;i<len;i++)
{
int sum=0;
for(int j=i;j>=0;j--)
{
if(s[j]=='0')
sum++;
}
for(int j=i+1;j<len;j++)
{
if(s[j]=='1')
sum++;
}
// cout<<i<<sum<<endl;
minn=min(minn,sum);
}
for(int i=0;i<len;i++)
{
int sum=0;
for(int j=i;j>=0;j--)
{
if(s[j]=='1')
sum++;
}
for(int j=i+1;j<len;j++)
{
if(s[j]=='0')
sum++;
}
// cout<<i<<sum<<endl;
minn=min(minn,sum);
}
cout<<minn<<endl;
}
}

赛后反思:

假如数据很大,就需要优化,对于第3,4情况,反转数实际上是某个位置之前的0数目+之后的1数目/之前的1数目+之后的0数目

所以这里可以用前缀和处理一下:46ms,可以说是快多了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e3+10;
int s1[maxn],s0[maxn];
int main()
{
int t;
cin>>t;
while(t--)
{
string s;
cin>>s;
memset(s1,0,sizeof(s1));
memset(s0,0,sizeof(s0));
int len=s.length();
if(len==1||len==2)
cout<<"0"<<endl;
else
{
if(s[0]=='0')
s0[0]++;
else
s1[0]++;
for(int i=1;i<len;i++)
{
s0[i]=s0[i-1];
s1[i]=s1[i-1];
if(s[i]=='0')
s0[i]++;
else
s1[i]++;
}
int minn=min(s1[len-1],s0[len-1]);
for(int i=0;i<len;i++)
{
minn=min(minn,s1[i]+s0[len-1]-s0[i]);
minn=min(minn,s0[i]+s1[len-1]-s1[i]);
}
cout<<minn<<endl;
}
}
}

C:​​http://codeforces.com/contest/1363/problem/C​​

题意:

n个结点,n-1条边,只能拿掉入度为0/1的点,谁先拿到x,谁赢。

解析:

当x入度为0/1的时候,直接先手胜

由于两个人都很聪明,每一步都要按最优来处理,所以谁都不想让对方赢,谁都不愿意先去靠近x,所以要把x点留到最后,即x入度==1的时候,这个时候,就确定了胜负了。

所以看一下,除了x之外的n-1个点的奇偶性,当然也可以看n-2的奇偶性,这个无所谓的。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=1e3+10;
int d[maxn];
int main()
{
int t;
cin>>t;
while(t--)
{
int n , x;
memset(d,0,sizeof(d));
cin>>n>>x;
for(int i=1;i<n;i++)
{
int l,r;
cin>>l>>r;
d[l]++;
d[r]++;
}
if(d[x]==0||d[x]==1)
cout<<"Ayush"<<endl;
else if((n-1)%2==0)
cout<<"Ashish"<<endl;
else
cout<<"Ayush"<<endl;
}
}

 



举报

相关推荐

0 条评论