Codeforces Round #563 (Div. 2)
题目链接:http://codeforces.com/contest/1174
A. Ehab Fails to Be Thanos
题意:给定一个长度为2n的数组a。有没有可能重新排序,使前n个元素的和不等于后n个元素的和?
思路:把数组a从小到大排好序,前n个元素和与后n个元素和不相等则一定存在这种可能
#include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <cstdio> #include <queue> #include <climits> #include <set> #include <stack> #include <string> #include <map> #include <vector> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; static const int MAX_N = 1e6 + 5; static const int N = 1005; static const ll Mod = 2009; int a[MAX_N]; void solve(){ // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int n; while(scanf("%d", &n) != EOF){ n <<= 1; for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); sort(a + 1, a + n + 1); int lefv = 0, rigv = 0; for(int i = 1; i <= n; ++i){ if(i <= (n >> 1)) lefv += a[i]; else rigv += a[i]; } if(lefv == rigv) puts("-1"); else for(int i = 1; i <= n; ++i) printf("%d%c", a[i], i == n ? '\n' : ' '); } } int main() { solve(); return 0; }
B. Ehab Is an Odd Person
题意:给定一个长度为n的数组a,你可以对它执行以下操作,次数不限:选择两个整数i,j(1≤i,j≤n) 如果ai+aj为奇数,则将ai与aj交换,你能得到的最小数组是多少?
思路:其实只要能够交换,就一定能够得到数组a所有元素从小到大排列的最小数组(即数组a中存在奇数和偶数 奇 + 偶 = 奇)
#include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <cstdio> #include <queue> #include <climits> #include <set> #include <stack> #include <string> #include <map> #include <vector> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; static const int MAX_N = 1e5 + 5; static const int N = 1005; static const ll Mod = 2009; int a[MAX_N], b[MAX_N]; void solve(){ // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int n; while(scanf("%d", &n) != EOF){ bool fg1 = false, fg2 = false; for(int i = 0; i < n; ++i){ scanf("%d", &a[i]); if(a[i] & 1) fg1 = true; else fg2 = true; } if(fg1 && fg2) sort(a, a + n); for(int i = 0; i < n; ++i) printf("%d%c", a[i], i == n - 1 ? '\n' : ' '); } } int main() { solve(); return 0; }
C. Ehab and a Special Coloring Problem
题意:给定一个整数n,对于从2到n的每一个整数i,分配一个正整数ai ,使下列条件成立:对于任意一对整数(i,j),如果i和j是coprime, ai≠aj,所有ai的最大值应该最小化(即尽可能小)。
如果一对整数的最大公约数是1,那么它们就称为coprime(互质)(1 <= a[i] <= n)
思路:质数与其它任何数之间都互质(对于所有的质数,从1开始枚举),非质数取它的因子a[i]值即可
#include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <cstdio> #include <queue> #include <climits> #include <set> #include <stack> #include <string> #include <map> #include <vector> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; static const int MAX_N = 1e5 + 5; static const int N = 1005; static const ll Mod = 2009; bool is_pr[MAX_N]; //判断是否为素数,0为是 int prime[MAX_N], pre[MAX_N], ans[MAX_N]; void prework(int n){ int cnt = 0; for(int i = 2; i <= n; ++i){ if(!is_pr[i]) prime[cnt++] = i; for(int j = 0; j < cnt; ++j){ int pr = prime[j]; int cur = pr * i; if(cur > n) break; is_pr[cur] = 1; pre[cur] = pr; if(i % pr == 0) break; } } } void solve(){ // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int n; while(scanf("%d", &n) != EOF){ prework(n); int id = 0; for(int i = 2; i <= n; ++i){ if(!is_pr[i]) ans[i] = ++id; else ans[i] = ans[pre[i]]; } for(int i = 2; i <= n; ++i) printf("%d%c", ans[i], i == n ? '\n' : ' '); } } int main() { solve(); return 0; }
D. Ehab and the Expected XOR Problem
题意:给定两个整数n和x,构造一个数组a,使得任意子段异或和不为0和x,同时数组a的长度应该最大化,对于a数组的元素(1 <= a[i] <= 2^n)
思路:在[1,2^n)之间开始枚举出异或和不为0和x的前缀数组,然后把前缀数组两两异或值输出即可得到任意子段异或和不为0和x的数组
#include <iostream> #include <cstring> #include <algorithm> #include <cmath> #include <cstdio> #include <queue> #include <climits> #include <set> #include <stack> #include <string> #include <map> #include <vector> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; static const int MAX_N = 2e5 + 5; static const int N = 1005; static const ll Mod = 2009; int ans[MAX_N]; void solve(){ // freopen("input.txt", "r", stdin); // freopen("output.txt", "w", stdout); int n, x; while(scanf("%d%d", &n, &x) != EOF){ int v = (1 << n); set<int>se; se.insert(0); int cnt = 0; for(int i = 1; i < v; ++i){ if(se.find(i ^ x) == se.end()){ ans[++cnt] = i; se.insert(i); } } printf("%d\n", cnt); for(int i = 1; i <= cnt; ++i) printf("%d%c", ans[i] ^ ans[i - 1], i == cnt ? '\n' : ' '); } } int main() { solve(); return 0; }