Educational Codeforces Round 134 (Rated for Div. 2) A-D
2A,C题wa2不知道为什么。B题少判一个条件:左上角
A :
题意有点不懂,到最后才知道是有多少种数,就输出这个种数-1即可
int n,m; void solve() { // cin>>n>>m; char s[4]; cin>>s[0]>>s[1]>>s[2]>>s[3]; set<int> q; fo(i,0,3) { q.insert(s[i]); } cout<< q.size() - 1<<endl; }
B:
有四种方法拦着可以让左上角的点到不了右下角:
1.左边和上面
2.右边和下面
3.左边和右边
4.上面和下面
const int N = 2000; int n,m,sx,sy,d; int dis(int x,int y) { return abs(x - y); } void solve() { cin>>n>>m>>sx>>sy>>d; if( dis(n,sx) <= d && dis(1,sx) <=d || dis(1,sy) <= d && dis(m,sy) <=d || dis(sy,m) <= d && dis(n,sx)<=d || dis(sx,1) <= d && dis(1,sy) <=d ) { cout<<-1<<endl;rt; } cout<<n + m - 2<<endl; }
C:
题意:输入a和b两个数组,a是有序的,b是排过序的,在 满足 b = a + di (d>=0) 的情况下,问每个di 的最小值和最大值
分情况考虑
最小值:说明 a 和 b 最近,找尽量前面的 b ,也就是找第一个比 a 大的 b 即可
为什么正确?
j <= i ,如果 bj >= ai ,说明 b[j,i] 都比 ai 大,ai 又比前面的所有 a 都大,所以满足条件
最大值:说明 a 和 b 最远,找尽量后面的 b ,怎么样使 ai 和 bj 互换,也能让所有 a[i+1,j] 都有比自己大的 bj 呢? 除了 bj ,离aj 最近的就是 bj-1,同理,离 aj-1最近的就是 bj-2,只要后面的 a能挨个和前面的 b 匹配, bj 就能跳过来和 ai匹配
ps:每遍历到一个 i ,j从 i 和 j中选一个最大的开始往后遍历,不用再管前面的数。
const int N = 2e5+10; int n,m; int a[N],b[N]; void solve() { cin>>n; fo(i,1,n) cin>>a[i]; fo(i,1,n) cin>>b[i]; int j = 1; fo(i,1,n) { while(j < n && a[i] > b[j] ) j ++ ; cout<<(b[j] - a[i]) <<' '; } cout<<endl; j = 1; fo(i,1,n) { j = max(j,i); while(j < n && b[j] >= a[j+1]) j ++ ; cout<<(b[j] - a[i]) <<' '; } cout<<endl; }
题意:有长度为 n 的两组 a 和 b ,随机交换 b 内数字的位置,得到 ci = ai ^ bi ,求使 c1 & c2 & c3 & c4 ....... 最大,求这个最大值
要使 c 的某一位 为 1,所有组 的(ai,bi) 必须能够通过交换次序 在这一位 不一样,
当所有组的ai 和 bi 在这一位,能够通过交换次序不一样,这一位才能为 1
然后把这些 a 和 b 分组
ai 如果在这一位是0,装在0的向量里,如果是 1 装在 1 的向量里
将ai 是 0 的情况 和 bi 是 1 的情况放在一同一组
ai 是 1 的情况 和 bi 是 0 的情况放在一同一组
这样 每一组的 ai 和 bi 的数目是一样的
然后根据上一层的分组,在每一组里看有没有可以在这一位匹配的。
每一组这样分,那会不会对下面的层不是最优解?
不会,因为上面已经分好了 0 1 已经是c 在上层的最优解,在这一层 c 是 1, 在下层有再多 1 也没这一层 c 是 1 大
高位匹配的 a 和 b 和低位匹配的a 和 b 位置 会不会 不一样?
不会,高位的 a b 匹配好了,并且会放在同一组里,低位只会使用在同一组的 a b
//#define int ll const int N = 1e5+10; int n,m; void solve() { int n; cin >> n; vector<int> a(n), b(n); fo(i,0,n-1) { cin>>a[i]; } fo(i,0,n-1) { cin>>b[i]; } int c = 0; for (int j = 29; j >= 0; j--) { map<int, int> mp; c |= 1 << j; for (int i = 0; i < n; i++) { mp[a[i] & c]++; mp[~b[i] & c]--; } bool flag = true; for (int x : a) { if (mp[x & c] != 0) { flag = false; break; } } if (!flag) c ^= (1 << j); } cout << c << "\n"; }