Codeforces#435

来源:互联网 发布:淘宝店铺公告图片尺寸 编辑:程序博客网 时间:2024/06/06 01:28

比赛地址:Codeforces Round #435 (Div. 2)
  这场的题目都挺有意思的!

C. Mahmoud and Ehab and the xor

题意:
  给定n与x,求n个不同的数,使它们异或之后等于x。
题解:

  1. 当n==2,x==0的时候无解
  2. 构造:
    1. pp = 1<<17;
    2. 构造1、2、…、n-3,异或值为y
    3. 如果x^y==0,那么构造pp,pp*2,pp^(pp*2)
    4. 如果x^y!=0,那么构造0,pp,pp^(x^y)

代码:

#include<iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <stack>using namespace std;int main() {    int n, x;    cin >> n >> x;    if (n == 2 && x == 0) {        cout << "NO" << endl;    }    else {        cout << "YES" << endl;        if (n == 1) {            cout << x << endl;        }        else if (n == 2) {            cout << 0 << " " << x << endl;        }        else {            int temp = 0;            int pp = 1 << 17;            for (int i = 0; i < n - 3; i++) {                cout << i + 1 << " ";                temp ^= (i + 1);            }            if (temp == x) {                cout << pp << " " << pp * 2 << " " << ((pp)^(pp * 2)) << endl;            }            else {                cout << 0 << " " << pp << " " << (pp ^ (x ^ temp)) << endl;            }        }    }    return 0;}

D. Mahmoud and Ehab and the binary string

题意:
  现在Evi有一个长度为n的隐藏字符串x(一定有一个1和一个0),现在你可以询问Evi,你给一个长度为n的字符串y,那么他会告诉你x与y有多少位不同。
  现在告诉你长度n,你必须在15次询问之内,确定x中一个1和一个0的位置。
题解:
  那么我们首先用一个全是0的字符串去询问,那么返回值num就是字符串中1的个数。
  然后呢,因为原字符串中一定有一个1和一个0,并且又全部由1和0组成,那么一定能找到一个相邻位置l和r,他们是01或者10,那么我们用二分法来找这个l和r.
  首先令l == 0 , r == N-1
  那么我们判断一下[mid,r]中是否全是1或者0
  怎么判断呢,我们这个时候用一个0–(mid-1)全是0,mid–r全是1,r–N-1全是0的串去询问,如果结果为num-(r-l+1)那么[mid,r]中是否全是1,如果结果为num+(r-l+1)那么[mid,r]中是否全是0,这种情况另r=mid。否则这中间既有1又有0,另l=mid.
  那么二分策略就出来了。
代码:

#include<iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <stack>using namespace std;int N, num;bool check(int l, int r) {    cout << "? ";    for (int i = 0; i < l; i++) {        cout << "0";    }    for (int i = l; i <= r; i++) {        cout << "1";    }    for (int i = r + 1; i < N; i++) {        cout << "0";    }    puts("");    fflush(stdout);    int temp;    cin >> temp;    if (temp > num - (r - l + 1) && temp < num + (r - l + 1)) {        return true;    }    else {        return false;    }}int main() {    cin >> N;    cout << "? ";    for (int i = 0; i < N; i++) {        cout << "0";    }    puts("");    fflush(stdout);    cin >> num;    int l = 0, r = N - 1;    while (r > l + 1) {        int mid = (l + r) / 2;        if (check(mid, r)) {            l = mid;        }        else {            r = mid;        }    }    cout << "? ";    for (int i = 0; i < l; i++) {        cout << "0";    }    for (int i = l; i < r; i++) {        cout << "1";    }    for (int i = r; i < N; i++) {        cout << "0";    }    puts("");    fflush(stdout);    int temp;    cin >> temp;    if (temp > num ) {        cout << "! " << l + 1 << " " << r + 1 << endl;    }    else {        cout << "! " << r + 1 << " " << l + 1 << endl;    }    return 0;}

E. Mahmoud and Ehab and the function

题意:
  略。。。
题解:
  推推公式,每次二分找一下就是的,太简单。
代码:

#include<iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <stack>using namespace std;long long a[100010], b[100010];long long n, m, q;long long sum[100010];long long cnt1, cnt2;long long get(int l, int r, long long val) {    if ((r - l + 1) & 1) {        if (l & 1) {            cnt1 += val;        }        else {            cnt1 -= val;        }    }    long long* pos = upper_bound(sum, sum + m - n + 1, -cnt1);    long long ans;    if (pos >= sum + m - n + 1) {        pos--;        ans = abs(*pos + cnt1);    }    else if (pos == sum) {        ans = abs(*pos + cnt1);    }    else {        ans = abs(*pos + cnt1);        pos--;        ans = min(ans, abs(*pos + cnt1));    }    return ans;}int main() {    cin >> n >> m >> q;    cnt1 = cnt2 = 0;    int f = 1;    for (int i = 1; i <= n; i++) {        cin >> a[i];        cnt1 += f * a[i];        f *= -1;    }    for (int i = 1; i <= m; i++) {        cin >> b[i];        if (i <= n) {            if (i & 1) {                cnt2 -= b[i];            }            else {                cnt2 += b[i];            }        }    }    sum[0] = cnt2;    for (int i = n + 1; i <= m; i++) {        cnt2 += b[i - n];        cnt2 *= -1;        if (n & 1) {            cnt2 -= b[i];        }else{            cnt2 += b[i];        }        sum[i - n] = cnt2;    }    sort(sum, sum + m - n + 1);    cout << get(1, 1, 0) << endl;    for (int i = 0; i < q; i++) {        int l, r, x;        cin >> l >> r >> x;        cout << get(l,r,x) << endl;    }    return 0;}
原创粉丝点击