当前位置: 移动技术网 > IT编程>开发语言>C/C++ > codechef September Challenge 2018 Division 2 A-F

codechef September Challenge 2018 Division 2 A-F

2018年09月18日  | 移动技术网IT编程  | 我要评论

vogue下载,湘潭县人口网,乱世玫瑰全集在线观看

比赛链接

上紫啦hhh,好开心

每个题里面都有中文翻译,我就不说题意了。。

a

直接模拟即可

#include<cstdio>
#include<algorithm>
#define int long long 
using namespace std;
const int maxn = 1e5 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int t;
int a[maxn], pos, q, n;
main() {
    t = read();
    while(t--) {
        n = read(); pos = read(); q = read();
        for(int i = 1; i <= n; i++) a[i] = i;
        while(q--) {
            int x = read(), y = read();
            swap(a[x], a[y]);
        }
        for(int i = 1; i <= n; i++)
            if(pos == a[i]) {
                printf("%d\n", i); break;
            }
    }
}
a

b

这题我交了五遍没过,捂脸,然而并不知道自己哪里错了

跟lyq说了说还被婊了一顿。。。。最后换了个写法a了。。

直接大力特判就行,至于哪个share什么玩意儿就让n-1,m-1,然后判是否可行

#include<cstdio>
using namespace std;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int n, m, x, y;
int pd(int n, int m) {
    /*if(n == 0 && m == 0) return 1;
    else if((n < x) || (m < y)) return 0;
    else if(n % x == 0 && m % y == 0) return 1;
    else return 0;*/
    if(n < 0 || m < 0) return 0;
    return n % x == 0 && m % y == 0;
}
int main() {
    int t;
    scanf("%d", &t);
    while(t--) {
        n = read(), m = read(), x = read(), y = read();
        n--; m--;
        if(pd(n, m)) {puts("chefirnemo"); continue;}
        n--; m--;
        if(pd(n, m)) {puts("chefirnemo"); continue;}
        puts("pofik");
    }
    return 0;
}
b

 

c

这题就有点厉害了!

结论:哥德巴赫猜想在信息学奥赛的范围内是成立的!

也就是说,任意一个$>=4$的偶数都是合法的。

然后把奇数和$0$判掉,维护出$0, 1$的个数即可

#include<cstdio>
#define ll long long 
using namespace std;
const int maxn = 1e6 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int t;
int n;
int a[maxn];
ll tim[maxn];
ll calc(ll x) {
    return x * (x - 1) / 2;
}
int main() {
  //  printf("%d", 2 ^ 4);
    t = read();
    while(t--) {
        n = read();
        for(int i = 1; i <= n;i ++) a[i] = read(), tim[a[i]]++;
        ll ans = 0, ze = 0, on = 0;
        /*for(int i = 1; i <= n; i++) {
            for(int j = i + 1; j <= n; j++) {
                int x = (a[i] ^ a[j]);
                if((!(x & 1)) && (x != 2) && (x != 0)) ans++;
            }
        }*/

        for(int i = 1; i <= n; i++)
            if(a[i] & 1) on++;
            else ze++;
        ans = calc(ze) + calc(on);
        //printf("%d\n", ans);
        ll a1 = 0;
        for(int i = 1; i <= n; i++)
            a1 += tim[a[i] ^ 2];
        ans -= a1 / 2;
        for(int i = 1; i <= n; i++) {
            ans -= (tim[a[i]] * (tim[a[i]] - 1)) / 2, tim[a[i]] = 0;
        }
        printf("%lld\n", ans);
    }
    return 0;
}
c

 

d

爆搜打出前$8$的表,不难找到规律:

最小的一定是$n, 1, 2, 3, \dots n - 1$

最大的是:$2, 3, 4, 5, n / 2, 1, 2 + n / 2, 3 + n / 2, 4 + n  /2 ...$

奇数的话还要特殊考虑一下倒数第二位

#include<cstdio>
#include<map>
#include<iostream>
#define ull unsigned long long 
#define ll long long 
using namespace std;
const int maxn = 1e6 + 10, inf = 1e9 + 7;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int n;
int ans[maxn], num;
int main() {
//    freopen("a.out", "w", stdout);
    n = read();
    
    for(int i = 2; i <= n / 2; i++) ans[++num] = i; 
    ans[++num] = 1;
    for(int i = 2; i <= n / 2; i++) ans[++num] = n / 2 + i;
    ans[++num] = 1 + n / 2;
    for(int i = 1; i <= num - 1; i++)
        printf("%d ", ans[i]);
    if(n & 1) printf("%d ", n);
    printf("%d\n", ans[num]);
    printf("%d ", n);
    for(int i = 1; i <= n - 1; i++)
        printf("%d ",i);
    return 0;
}
d

 

e

首先考虑暴力怎么打,我们把给出的初始行列的01取反,这样$0$的时候对应的是必胜态,$1$对应的是必败态。

然后按博弈论的定义推,$(i, j)$若是必胜态,那么至少有$(i - 1, j)$是必败态 或者 $(i, j - 1)$是必败态。

然后暴力枚举一遍就行了,复杂度$o(nm)$

接下来的操作就比较神仙了,,打表 或 直接观察式子可得,若第$(i, j)$个点是必败点,那么它所在的对角线往后的点,都是必败点!

这样我们就把状态降到了$2 * m$

那最开始的必败点怎么求呢?

直觉告诉我们 稍加证明不难得到,这种点一定是出现在前两行 或者前两列。

然后就做完了。

暴力推前两行 前两列即可。

保险起见我推了三行三列。

#include<cstdio>
#include<cstring>
#include<vector>
#define ll long long 
using namespace std;
const int maxn = 1e5 + 10;
inline ll read() {
    char c = getchar(); ll x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int t;
int a[4][maxn], b[maxn][4], n, m, f[maxn], g[maxn];
char a[maxn], b[maxn];
int main() { 
//-    freopen("a.out", "w", stdout);
    int t = read();
    while(t--) {
        scanf("%s", a + 1);
        scanf("%s", b + 1);
        m = strlen(a + 1);
        n = strlen(b + 1);
        for(int i = 1; i <= m; i++) a[0][i] = (a[i] == '1' ? 0 : 1);
        for(int i = 1; i <= 3; i++) a[i][0] = (b[i] == '1' ? 0 : 1);
        
        for(int i = 1; i <= 3; i++) b[0][i] = (a[i] == '1' ? 0 : 1);
        for(int i = 1; i <= n; i++) b[i][0] = (b[i] == '1' ? 0 : 1);
        
        memset(f, 0x7f, sizeof(f));
        memset(g, 0x7f, sizeof(g));
        
        for(int i = 1; i <= 3; i++) {
            for(int j = 1; j <= m; j++) {
                if(a[i - 1][j] == 1 || a[i][j - 1] == 1) a[i][j] = 0;//能到达必败节点的 
                else a[i][j] = 1;
                if(a[i][j] == 1) f[j - i + 1] = min(f[j - i + 1], i);
            }
        }
        
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= 3; j++) {
                if(b[i - 1][j] == 1 || b[i][j - 1] == 1) b[i][j] = 0;
                else b[i][j] = 1;
                if(b[i][j] == 1) g[i - j + 1] = min(g[i - j + 1], j);
            }
        }
        vector<int> ans;
        int q = read();
        while(q--) {
            int x = read(), y = read();
            int dy = y - x + 1,
                dx = x - y + 1;
            if(dy >= 1) {
                if(x >= f[dy]) ans.push_back(0);
                else ans.push_back(1); 
            } else {
                if(y >= g[dx]) ans.push_back(0);
                else ans.push_back(1);
            }
        }
        for(int i = 0; i < ans.size(); i++) printf("%d", ans[i]);        
        puts("");
    }

    return 0;
}
e

f

这个题我就不说啥了,challenge题嘛,xjb乱搞。

但是!!!

我tm辛辛苦苦写了半天的贪心324分??

直接输出$1$有400+????????????

 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网