Codeforces Round #563 (Div. 2)
CF
题目链接:https://codeforces.com/contest/1174
总结
ABC都比较水,27分钟写完了,但是D题想偏了,一直WA,AC代码确实太巧妙了。
A题
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 100050
int n,sum1,sum2,a[N];
template<typename T>void read(T&x)
{
ll k=0; char c=getchar();
x=0;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit(0);
while(isdigit(c))x=x*10+c-'0',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
read(n);
for(int i=1;i<=2*n;i++)read(a[i]);
sort(a+1,a+n*2+1);
for(int i=1;i<=n;i++)sum1+=a[i];
for(int i=n+1;i<=2*n;i++)sum2+=a[i];
if (sum1==sum2){printf("-1");return 0;}
for(int i=1;i<=2*n;i++)printf("%d ",a[i]);
B题
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 100050
int n,sum1,sum2,a[N],f[3];
template<typename T>void read(T&x)
{
ll k=0; char c=getchar();
x=0;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit(0);
while(isdigit(c))x=x*10+c-'0',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
read(n);
for(int i=1;i<=n;i++)read(a[i]),f[a[i]%2]++;
if (f[0]>0&&f[1]>0)sort(a+1,a+n+1);
for(int i=1;i<=n;i++)printf("%d ",a[i]);
}
C题
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 100050
int n,ans,a[N],f[N];
template<typename T>void read(T&x)
{
ll k=0; char c=getchar();
x=0;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit(0);
while(isdigit(c))x=x*10+c-'0',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
read(n);
for(int i=2;i<=n;i++)
{
if (f[i]==0)
{
ans++;
f[i]=ans;
int x=i;
while(x+i<=n)f[x+i]=ans,x+=i;
}
}
for(int i=2;i<=n;i++)printf("%d ",f[i]);
}
D题
题意:
一道构造题,给你n,x 构造尽量长的序列\({a_l}\),满足:
\[\begin{aligned}
&\bullet 1\le a_i\le 2^n \\
&\bullet 没有一个子序列的异或和等于零或x
\end{aligned}
\]
题解
首先假设我们已经知道了这个序列,另s[i]表示i的亦或前缀和,那么对于任意一段子序列(i,j)都可以用s[i]^s[j]表示,
所以也就是不存在s[i]^s[j]=0或x。
所以我们可以先构造s[i]数组,不难发现一个性质:s[i]一定小于\(2^n\),我们从\(1->2^n\)枚举,如果s[i]=k,那么k^x和k就不能再出现。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 1000050
int n,num,f[N],a[N];
template<typename T>void read(T&x)
{
ll k=0; char c=getchar();
x=0;
while(!isdigit(c)&&c!=EOF)k^=c=='-',c=getchar();
if (c==EOF)exit(0);
while(isdigit(c))x=x*10+c-'0',c=getchar();
x=k?-x:x;
}
void read_char(char &c)
{while(!isalpha(c=getchar())&&c!=EOF);}
int main()
{
#ifndef ONLINE_JUDGE
freopen("aa.in","r",stdin);
#endif
int x;
read(n); read(x);
int all=(1<<n)-1;
f[x]=1;
for(int i=1;i<=all;i++)if (!f[i]){a[++num]=i;f[i^x]=1;}
printf("%d\n",num);
for(int i=1;i<=num;i++)
printf("%d ",a[i]^a[i-1]);
}