Codeforces Round #770 (Div. 2) ABCD题解
A. Reverse and Concatenate
思路:
答 案 要 么 1 要 么 2 答案要么1要么2 答案要么1要么2
等 于 1 的 必 要 条 件 是 反 转 之 后 是 它 本 身 等于1的必要条件是反转之后是它本身 等于1的必要条件是反转之后是它本身
反 之 就 是 2 反之就是2 反之就是2
时间复杂度: O n On On
#define sf(x) scanf("%d",&x)
#define all(x) (x).begin(),(x).end()
#define cf int _; cin>> _; while(_--)
inline void sf2(int &a , int &b) { sf(a) , sf(b) ;}
signed main()
{cf{int n , m ;sf2(n, m);string s;cin >> s;string ans = s;reverse(all(s));if (s != ans && m)puts("2");elseputs("1");}return 0;
}
B. Fortune Telling
思路:
注 意 到 x 和 x + 3 奇 偶 性 不 同 注意到x和x+3奇偶性不同 注意到x和x+3奇偶性不同
如 果 a 是 奇 数 , b 是 偶 数 如果a是奇数,b是偶数 如果a是奇数,b是偶数
假 设 x 是 奇 数 假设x是奇数 假设x是奇数
a + = x 是 偶 数 a+=x是偶数 a+=x是偶数
b + = x 是 奇 数 b+=x是奇数 b+=x是奇数
a ⊕ = x 是 偶 数 a\oplus=x是偶数 a⊕=x是偶数
b ⊕ = x 是 奇 数 b\oplus=x是奇数 b⊕=x是奇数
x 是 偶 数 同 理 x是偶数同理 x是偶数同理
我 们 发 现 a 和 b 的 奇 偶 性 一 直 是 相 对 的 我们发现a和b的奇偶性一直是相对的 我们发现a和b的奇偶性一直是相对的
如 果 x 是 偶 数 a b 奇 偶 性 不 变 如果x是偶数ab奇偶性不变 如果x是偶数ab奇偶性不变
如 果 x 是 奇 数 a b 奇 偶 性 交 换 如果x是奇数ab奇偶性交换 如果x是奇数ab奇偶性交换
题 目 最 后 一 句 话 题目最后一句话 题目最后一句话
exactly one of your friends could have actually gotten that number.
说 明 答 案 必 定 存 在 说明答案必定存在 说明答案必定存在
所 以 统 计 奇 数 个 数 即 可 所以统计奇数个数即可 所以统计奇数个数即可
说 点 题 外 话 , 奇 偶 性 这 个 性 质 c f 经 常 考 , 可 以 多 做 做 类 似 的 题 说点题外话,奇偶性这个性质cf经常考,可以多做做类似的题 说点题外话,奇偶性这个性质cf经常考,可以多做做类似的题
时间复杂度: O n On On
#define fer(i,a,b) for(int i = a ; i <= b ; ++ i)
#define cf int _; cin>> _; while(_--)
const int N = 1e6 + 10 ;
int n ;
int a[N] , x , y ;signed main()
{cf{cin >> n >> x >> y ;int cnt = 0 ;fer(i,1,n){sf(a[i]) ;if(a[i] & 1) cnt ++ ;}if(x & 1){if(y & 1){if(cnt % 2 == 0) puts("Alice") ;else puts("Bob") ;}else{if(cnt % 2) puts("Alice") ;else puts("Bob") ;}}else {if(y & 1){if(cnt % 2 == 0) puts("Bob") ;else puts("Alice") ;}else{if(cnt % 2) puts("Bob") ;else puts("Alice") ;}}}return 0;
}
C. OKEA
思路:
n 是 偶 数 或 者 k < = 1 可 以 , 否 则 都 不 可 以 n是偶数或者k<=1可以,否则都不可以 n是偶数或者k<=1可以,否则都不可以
时间复杂度: O n k Onk Onk
#define fer(i,a,b) for(int i = a ; i <= b ; ++ i)
#define cf int _; cin>> _; while(_--)
signed main()
{cf{int n , k ;cin >> n >> k ;if(n % 2 == 0){puts("YES") ;int cnt = 0 ;for(int i = 1 ; i <= n * k ; i += 2){cnt ++ ;cout << i << " " ;if(cnt == k){cnt = 0 ;puts("") ;}}for(int i = 2 ; i <= n * k ; i += 2){cnt ++ ;cout << i << " " ;if(cnt == k){cnt = 0 ;puts("") ;}}}else if(k <= 1){puts("YES") ;if(k == 1){fer(i,1,n*k){cout << i << "\n" ;}}}else puts("NO") ;}return 0;
}
D. Finding Zero
思路:
没 错 , d 题 想 了 快 2 h 才 做 出 来 没错,d题想了快2h才做出来 没错,d题想了快2h才做出来
有 个 超 级 超 级 重 要 的 性 质 有个超级超级重要的性质 有个超级超级重要的性质
经 过 了 漫 长 时 间 的 思 考 以 及 草 稿 纸 上 的 举 不 出 反 例 才 得 到 的 结 果 经过了漫长时间的思考以及草稿纸上的举不出反例才得到的结果 经过了漫长时间的思考以及草稿纸上的举不出反例才得到的结果
第 一 次 假 设 三 个 数 a [ x ] , a [ y ] , a [ z ] 的 下 标 是 1 , 2 , 3 第一次假设三个数a[x],a[y],a[z]的下标是1,2,3 第一次假设三个数a[x],a[y],a[z]的下标是1,2,3
假 设 当 前 差 值 为 l a s t 假设当前差值为last 假设当前差值为last
差 值 就 是 最 大 值 − 最 小 值 , 也 就 是 询 问 x , y , z 的 结 果 差值就是最大值-最小值,也就是询问x,y,z的结果 差值就是最大值−最小值,也就是询问x,y,z的结果
做 2 次 循 环 做2次循环 做2次循环
第 一 次 用 4 到 n 的 每 一 个 数 去 替 换 掉 第 三 个 数 第一次用4到n的每一个数去替换掉第三个数 第一次用4到n的每一个数去替换掉第三个数
如 果 当 前 差 值 大 于 等 于 > = l a s t 如果当前差值大于等于>=last 如果当前差值大于等于>=last
就 替 换 掉 第 三 个 数 , 同 时 更 新 l a s t = 当 前 差 值 , 否 则 不 替 换 就替换掉第三个数,同时更新last=当前差值,否则不替换 就替换掉第三个数,同时更新last=当前差值,否则不替换
同 理 , 第 二 次 循 环 替 换 掉 第 二 个 数 同理,第二次循环替换掉第二个数 同理,第二次循环替换掉第二个数
同 时 更 新 l a s t 同时更新last 同时更新last
两 次 循 环 之 后 , a [ x ] , a [ y ] , a [ z ] 必 定 存 在 0 和 当 前 数 组 中 的 最 大 值 两次循环之后,a[x],a[y],a[z]必定存在0和当前数组中的最大值 两次循环之后,a[x],a[y],a[z]必定存在0和当前数组中的最大值
那 怎 么 找 到 0 和 最 大 值 呢 那怎么找到0和最大值呢 那怎么找到0和最大值呢
有 个 逻 辑 是 这 样 的 , 你 找 另 外 一 个 下 标 i d 有个逻辑是这样的,你找另外一个下标id 有个逻辑是这样的,你找另外一个下标id
询 问 i d , y , z 的 结 果 询问id,y,z的结果 询问id,y,z的结果
如 果 当 前 差 值 = l a s t , 说 明 a [ x ] 一 定 不 是 0 , 那 么 输 出 y , z 即 可 如果当前差值=last,说明a[x]一定不是0,那么输出y,z即可 如果当前差值=last,说明a[x]一定不是0,那么输出y,z即可
同 理 当 前 差 值 ! = l a s t , 那 就 用 i d 替 换 y / z 同理当前差值!=last,那就用id替换y/z 同理当前差值!=last,那就用id替换y/z
题 外 话 题外话 题外话
一 开 始 的 三 个 数 的 下 标 不 一 定 非 得 是 1 , 2 , 3 , 任 意 三 个 不 同 的 下 标 都 可 一开始的三个数的下标不一定非得是1,2,3,任意三个不同的下标都可 一开始的三个数的下标不一定非得是1,2,3,任意三个不同的下标都可
两 次 循 环 不 一 定 非 得 替 换 第 二 个 数 和 第 三 个 数 , 任 意 2 个 数 皆 可 两次循环不一定非得替换第二个数和第三个数,任意2个数皆可 两次循环不一定非得替换第二个数和第三个数,任意2个数皆可
这 个 性 质 可 以 在 草 稿 纸 上 仔 细 想 想 推 敲 推 敲 这个性质可以在草稿纸上仔细想想推敲推敲 这个性质可以在草稿纸上仔细想想推敲推敲
个 人 觉 得 举 不 出 来 反 例 在 算 法 竞 赛 当 中 往 往 是 较 为 正 确 的 证 明 个人觉得举不出来反例在算法竞赛当中往往是较为正确的证明 个人觉得举不出来反例在算法竞赛当中往往是较为正确的证明
时间复杂度: O n 2 On^2 On2
#define cf int _; cin>> _; while(_--)
signed main()
{cf{int n ;cin >> n ;int x = 1 , y = 2 , z = 3 ;int last ;cout << "? " << x << " " << y << " " << z << '\n' ;cout.flush() ;cin >> last ;for(int i = 4 ; i <= n ; i ++){cout << "? " << x << " " << y << " " << i << '\n' ;cout.flush() ;int k ;cin >> k ;if(k >= last){last = k ;z = i ;}}for(int i = 1 ; i <= n ; i ++){if(i == x || i == y || i == z) continue ;cout << "? " << x << " " << i << " " << z << '\n' ;cout.flush() ;int k ;cin >> k ;if(k >= last){last = k ;y = i ;}}int id = -1 ;for(int i = 1 ; i <= n ; i ++){if(i == x || i == y || i == z) continue ;id = i ;break ;}int k ;cout << "? " << id << " " << y << " " << z << '\n' ;cout.flush() ;cin >> k ;if(k == last){cout << "! " << y << " " << z << "\n" ;}else {cout << "? " << x << " " << id << " " << z << '\n' ;cout.flush() ;cin >> k ;if(k == last){cout << "! " << x << " " << z << "\n" ;}else{cout << "? " << x << " " << y << " " << id << '\n' ;cout.flush() ;cin >> k ;if(k == last){cout << "! " << x << " " << y << "\n" ;}else cout << "! " << x << " " << y << "\n" ;}}}return 0;
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
