这个A题很简单,就是排个序,然后看前面n个数和后面的n个数是不是相同,相同就输出-1
#include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #include <cstring> #include <algorithm> #include <vector> #include <iostream> #define inf 0x3f3f3f3f using namespace std; const int maxn = 1e4 + 10; typedef long long ll; int a[maxn]; int main() { int n; scanf("%d", &n); for (int i = 1; i <= 2*n; i++) scanf("%d", &a[i]); sort(a + 1, a + 1 + 2*n); ll sum1 = 0, sum2 = 0; 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\n"); else { for (int i = 1; i <= 2 * n - 1; i++) printf("%d ", a[i]); printf("%d\n", a[2 * n]); } return 0; }
这个B题我写的比C还慢,这个题目有一个规律就是如果这里面既存在奇数又存在偶数,那么就可以排成任意顺序。
#include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #include <cstring> #include <algorithm> #include <map> #include <vector> #include <iostream> #define inf 0x3f3f3f3f using namespace std; const int maxn = 1e5 + 10; typedef long long ll; int a[maxn]; int main() { int n; int odd = 0, even = 0; scanf("%d", &n); for(int i=1;i<=n;i++) { scanf("%d", &a[i]); if (a[i] & 1) odd++; else even++; } if(even==0||odd==0) { for (int i = 1; i <= n - 1; i++) printf("%d ", a[i]); printf("%d\n", a[n]); } else { sort(a + 1, a + 1 + n); for (int i = 1; i < n; i++) printf("%d ", a[i]); printf("%d\n", a[n]); } return 0; }
C. Ehab and a Special Coloring Problem
这个C其实比较简单,应该很容易就可以想到用素数筛吧。
#include <cstdio> #include <cstdlib> #include <cstring> #include <queue> #include <cstring> #include <algorithm> #include <map> #include <vector> #include <iostream> #define inf 0x3f3f3f3f using namespace std; const int maxn = 1e5 + 10; typedef long long ll; int isp[maxn], v[maxn], m; void init() { for(int i=2;i<=maxn;i++) { if(v[i]==0) { isp[m++] = i; v[i] = i; } for(int j=0;j<m;j++) { if (v[i]<isp[j] || i * isp[j]>maxn) break; v[i*isp[j]] = isp[j]; } } } int vis[maxn]; int a[maxn]; int main() { int n, num = 1; scanf("%d", &n); init(); for(int i=2;i<=n;i++) { if (vis[v[i]] == 0) vis[v[i]] = num++; a[i] = vis[v[i]]; } for (int i = 2; i < n; i++) printf("%d ", a[i]); printf("%d\n", a[n]); return 0; }
D. Ehab and the Expected XOR Problem
这个D题我觉得是存在难度的,这个D是一个异或问题,这就要求我们对异或的运算法则十分了解。
这个题目主要有两个限制,一个是小于2的n次方,第二个是既不可以有任意子串的异或值为0也不可以为x
这个我可以想到这些异或运算法则,但是不知道要怎么去处理。
最后看了lj大佬的题解,是用异或前缀和来处理。
首先我们可以知道,如果已知一个数列的异或和,那么我们就可以求出这个数列的每一个数
其次我们可以把从1到(1<<n)这些数字都当作一些数字的异或和,所以呢,
因为任意子串的异或值不可以为0,所以说明不可以有相同的前缀异或和放在一个集合中。
所以我们就分成两个集合,最后判断哪个集合更大输出哪个。
#include <cstdio> #include <cstdlib> #include <queue> #include <cstring> #include <queue> #include <vector> #include <algorithm> #include <map> #define inf 0x3f3f3f3f using namespace std; const int maxn = 5e5 + 10; vector<int>vec[2]; int vis[maxn]; int main() { int n, x; scanf("%d%d", &n, &x); int ex = (1 << n); for(int i=1;i<ex;i++) { if (i == x) continue; vis[i] = vis[x^i] ^ 1; vec[vis[i]].push_back(i); } int ans = 1; if (vec[0].size() > vec[1].size()) ans = 0; int len = vec[ans].size(); printf("%d\n", len); for(int i=0;i<len;i++) { if (i == 0) printf("%d ", vec[ans][i]); else printf("%d ", vec[ans][i] ^ vec[ans][i - 1]); } printf("\n"); return 0; }