感觉自己无可救药了。

A题:找到小于等于n的两个不同的数的gcd最大是多少,显然是floort(n/2)。设这两数是a * gcd, b * gcd然后gcd(a,b) = 1,那么gcd要尽量大,不妨就a = 1,b  = 2。

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#define rep(i,j,k) for(int i = j; i <= k; i++)
#define dow(i,j,k) for(int i = j; i >= k; i--)
#define fi first
#define se second
using namespace std; typedef long long ll;
typedef pair<int,int> pi; using namespace std;
int t;
int main() {
cin >> t;
while (t--) {
int n;
cin >> n;
n = n / ;
cout << n << endl;
}
}

B题:给定2n个数,从中去掉两个数。剩下的数配成n - 1对,然后要求这些对的和的最大gcd大于1。大于1,那就gcd等于2就好了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#define rep(i,j,k) for(int i = j; i <= k; i++)
#define dow(i,j,k) for(int i = j; i >= k; i--)
#define fi first
#define se second
using namespace std; typedef long long ll;
typedef pair<int,int> pi; const int N = ; int n, cnt[], t;
struct node{
int val, i;
}a[N*]; bool cmp(node x,node y) {
return (x.val & ) < (y.val & );
}
void solve() {
scanf("%d", &n);
cnt[] = cnt[] = ;
rep(i,, n * ) scanf("%d", &a[i].val), a[i].i = i,cnt[a[i].val & ]++;
sort(a + , a + n * + , cmp);
if (cnt[] & ) {
for(int i = ; i < n * ; i+=) {
printf("%d %d\n", a[i].i, a[i+].i);
}
return;
}
for(int i = ; i < n * - ; i+=) {
printf("%d %d\n", a[i].i, a[i+].i); }
return ;
} int main() {
scanf("%d", &t);
while(t--) {
solve();
}
}

C题:game题,给一个数n,每次可以减1,如果有奇数因子可以除以奇数因子(包括本身),轮流操作,到1就输了。不知道有什么好做法,写了一堆if。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#define rep(i,j,k) for(int i = j; i <= k; i++)
#define dow(i,j,k) for(int i = j; i >= k; i--)
#define fi first
#define se second
using namespace std; typedef long long ll;
typedef pair<int,int> pi; const int N = ; int dp[N];
bool isprime(int x) {
for(int i = ; i * i <= x; i++) {
if (x % i == ) return ;
}
return ;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
if (n == ) {
printf("FastestFinger\n");
}
else if (n == ) {
puts("Ashishgup");
}
else if (n & ) {
puts("Ashishgup");
}
else{
int cnt = ;
while (n % ==) cnt++, n /= ;
if (n == ) {
puts("FastestFinger");
}
else if (cnt == ) {
if (isprime(n)) puts("FastestFinger");
else puts("Ashishgup");
}
else puts("Ashishgup");
}
}
}

D题:从一个数组里找一个长度为k的子序列,子序列的代价是,子序列的奇数位和偶数位中的最大值中的较小的值。猜测二分贪心是个好做法,然后过了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#define rep(i,j,k) for(int i = j; i <= k; i++)
#define dow(i,j,k) for(int i = j; i >= k; i--)
#define fi first
#define se second
using namespace std; typedef long long ll;
typedef pair<int,int> pi; const int N = ; int n, k;
int a[N]; bool solve(int x) {
int f = ;
int cnt = ;
rep(i,,n) {
if (cnt % == ) cnt++;
else if (a[i] <= x) cnt++;
}
if (cnt >= k) return ;
cnt = ;
rep(i,,n) {
if (cnt & ) cnt++;
else if(a[i] <= x) cnt++;
}
if (cnt >= k) return ;
return ;
} int main() {
scanf("%d %d", &n, &k);
rep(i,,n) scanf("%d", &a[i]);
int l = , r = 1e9;
while (l < r) {
//cerr << l << " " << r << endl;
int mid = (l + r) >> ;
if (solve(mid)) r = mid;
else l = mid + ;
}
printf("%d\n", l);
}

E题:给你两个长度相等的01串,每次可以选择第一个串中的一个子序列,对子序列进行循环右移(不太会简单描述这个操作),然后问最少多少次可以让两个串一样,或者无法实现。

如果两个串01数量不想等就不行,否则就可以。而且我们直接忽视掉已经匹配的位置。然后第一个串就是一堆01,现在要让0到1的位置,1到0的位置。最直接的方法直接配对然后全部循环右移即可。

01可以一次变10。发现010101可以一次变101010也就是说交替的01一次做能减少我们的操作次数。然后就找一下每个0能不能找到交替的1。然后就瞎写了写就莫名其妙过了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#define rep(i,j,k) for(int i = j; i <= k; i++)
#define dow(i,j,k) for(int i = j; i >= k; i--)
#define fi first
#define se second
using namespace std; typedef long long ll;
typedef pair<int,int> pi; const int N = 1e6 + ;
int n;
char s[N], t[N];
int a[N];
int tot;
int ans;
//int lens, lent
int cnts, cntt;
int main() {
scanf("%d", &n);
scanf("%s", s + );
scanf("%s", t + );
rep(i,,n) if (s[i] == '') cnts++;
rep(i,,n) if (t[i] == '') cntt++;
if (cnts != cntt) {
puts("-1");
return ;
}
// int tot = 0;
rep(i,,n) {
if (s[i] == t[i]) continue;
a[++tot] = s[i] - '';
}
ans = tot;
//cerr << tot << "!!!" << endl;
//rep(i,1,tot) cerr << a[i] << " "; cerr << endl;
int j = ;
rep(i,,tot) {
if (a[i] != ) continue;
j = max(i, j);
while (a[j] == && j <= tot) j++;
if (j <= tot) {
ans--;
j++;
}
}
j = tot;
dow(i,tot,) {
if (a[i] != ) continue;
j = min(i, j);
while (a[j] == && j >= ) j--;
if (j >= ) {
ans --;
j--;
}
}
printf("%d\n", ans);
}

f:一个树上,有两个hidden的点。每次询问一个点集,返回到两点距离之和最小的一个点和到两点的距离之和。11次之内搞出来。1000个点

并不会做。然后就等第二天看题解了。

询问所有点,找出两点间路径上的一个点,然后二分,询问深度为mid的所有点,如果说返回的距离大于第一次询问的点,深度就过深了,然后10次内就能搞出某个hidden的点,然后就知道另一个点的深度再询问一次就好。

如果两点距离为d,那么至少有一个点深度是ceil(d / 2),那么就相当于使二分的边界少了一半,11次就能搞定。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#define rep(i,j,k) for(int i = j; i <= k; i++)
#define dow(i,j,k) for(int i = j; i >= k; i--)
#define fi first
#define se second
using namespace std; typedef long long ll;
typedef pair<int,int> pi; const int N = ; struct edge{
int to,next;
}e[N << ];
int n, cnt, h[N];
int dep[N];
int rt, d;
pi ans[N];
int vis[N];
void add(int u,int v) {
e[++cnt] = (edge) {v, h[u]}; h[u] = cnt;
} void dfs(int x) {
for (int i = h[x]; i; i = e[i].next) {
int v = e[i].to;
if (!dep[v] && v != rt) dep[v] = dep[x] + , dfs(v);
}
}
void dfs2(int x, vector<int> &cnt, int dis) {
vis[x] = ;
if(dis == d) {
cnt.push_back(x);
return ;
}
for (int i = h[x]; i; i = e[i].next) {
int v = e[i].to;
if (!vis[v]) dfs2(v, cnt, dis + );
}
}
void solve() {
cnt = ;
int x, y;
int a = , b = ;
memset(h, , sizeof(h));
memset(dep, , sizeof(dep));
memset(ans, , sizeof(ans));
scanf("%d", &n);
rep(i,,n-) {
int u, v;
scanf("%d %d", &u, &v);
add(u, v); add(v, u);
}
printf("? %d ", n);
rep(i,,n) printf("%d ", i); puts("");
fflush(stdout);
scanf("%d %d", &rt, &d);
int l = (d + ) / , r = d;
dfs(rt);
ans[] = make_pair(rt, d);
while() {
int mid = (l + r + ) >> ;
if (!ans[mid].fi) {
vector<int> temp;
rep(i,,n) if (dep[i] == mid) temp.push_back(i);
int cnt = temp.size();
if (cnt == ) {
r = mid - ;
continue;
}
printf("? %d ", cnt);
rep(i,,cnt-) printf("%d ", temp[i]); puts("");
fflush(stdout);
scanf("%d %d", &x, &y);
ans[mid] = make_pair(x, y);
} if (ans[mid].se > d) r = mid - ;
else l = mid;
if (l == r && l == mid) {a = ans[l].fi; break;}
} vector<int> temp;
memset(vis, , sizeof(vis));
dfs2(a, temp, );
int cnt = temp.size();
if (cnt == ) b = temp[];
else {
printf("? %d ", cnt);
rep(i,, cnt - ) printf("%d ", temp[i]); puts("");
fflush(stdout);
scanf("%d %d", &x, &y);
b = x;
}
printf("! %d %d\n", a, b);
string s;
fflush(stdout);
cin >> s;
} int main() {
int t;
scanf("%d", &t);
while (t--) {
solve();
}
}

感觉自己明明d、e都不会做就是瞎蒙对的……

然后交互题尽量应该把交互的过程封装一下。

Codeforces Round #651 (Div. 2)的更多相关文章

  1. Codeforces Round #651 (Div. 2) A. Maximum GCD(数论)

    题目链接:https://codeforces.com/contest/1370/problem/A 题意 有 $n$ 个数大小分别为 $1$ 到 $n$,找出两个数间最大的 $gcd$ . 题解 若 ...

  2. Codeforces Round #651 (Div. 2) B. GCD Compression(数论)

    题目链接:https://codeforces.com/contest/1370/problem/B 题意 给出 $2n$ 个数,选出 $2n - 2$ 个数,使得它们的 $gcd > 1$ . ...

  3. Codeforces Round #651 (Div. 2) C. Number Game(数论)

    题目链接:https://codeforces.com/contest/1370/problem/C 题意 给出一个正整数 $n$,Ashishgup 和 FastestFinger 依次选择执行以下 ...

  4. Codeforces Round #651 (Div. 2) D. Odd-Even Subsequence(二分)

    题目链接:https://codeforces.com/contest/1370/problem/D 题意 给出一个含有 $n$ 个数的数组 $a$,从中选出 $k$ 个数组成子序列 $s$,使得 $ ...

  5. Codeforces Round #651 (Div. 2) E. Binary Subsequence Rotation(dp)

    题目链接:https://codeforces.com/contest/1370/problem/E 题意 给出两个长为 $n$ 的 $01$ 串 $s$ 和 $t$,每次可以选择 $s$ 的一些下标 ...

  6. Codeforces Round #651 (Div. 2) A Maximum GCD、B GCD Compression、C Number Game、D Odd-Even Subsequence

    A. Maximum GCD 题意: t组输入,然后输入一个n,让你在区间[1,n]之间找出来两个不相等的数a,b.求出来gcd(a,b)(也就是a,b最大公约数).让你求出来最大的gcd(a,b)是 ...

  7. Codeforces Round #651 (Div. 2) C. Number Game (博弈,数学)

    题意:对于正整数\(n\),每次可以选择使它变为\(n-1\)或者\(n/t\) (\(n\ mod\ t=0\)且\(t\)为奇数),当\(n=1\)时便不可以再取,问先手赢还是后手赢. 题解:首先 ...

  8. Codeforces Round #651 (Div. 2) B. GCD Compression (构造)

    题意:有一个长度为\(2n\)的数组,删去两个元素,用剩下的元素每两两相加构造一个新数组,使得新数组所有元素的\(gcd\ne 1\).输出相加时两个数在原数组的位置. 题解:我们按照新数组所有元素均 ...

  9. Codeforces Round #651 (Div. 2) A. Maximum GCD (思维)

    题意:在\(1\)~\(n\)中找两个不相等的数使得他们的\(gcd\)最大. 题解:水题,如果\(n\)是偶数,那么一定取\(n\)和\(n/2\),\(n\)是奇数的话,取\(n-1\)和\((n ...

随机推荐

  1. sqlmap中文手册

    Sqlmap中文手册  -Darren制作 零.前言 Sqlmap是十分著名的.自动化的SQL注入工具.为了较为系统地学习Sqlmap,我决定翻译一遍Sqlmap的用户手册,于是便有了此文.由于我英语 ...

  2. Alpha冲刺——4.30

    这个作业属于哪个课程 软件工程 这个作业要求在哪里 团队作业第五次--Alpha冲刺 这个作业的目标 Alpha冲刺 作业正文 正文 github链接 项目地址 其他参考文献 无 一.会议内容 1.规 ...

  3. Chisel3 - util - Mux

    https://mp.weixin.qq.com/s/TK1mHqvDpG9fbLJyNxJp-Q   Mux相关电路生成器.   参考链接: https://github.com/freechips ...

  4. jchdl - RTL实例 - MOS6502 SoC

    https://mp.weixin.qq.com/s/H2UBmZa9fpM6_FM2_MucTQ   实现一个SoC作为顶层模块,包含Cpu.Mem两个子模块,并驱动运行.   参考链接 https ...

  5. JavaSE (五)面向对象 -- 概述

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 目录 一.面向对象的主线 二.面向对象 VS 面向过程 三 . java最基本的两个要素 - 类和对象 ...

  6. 一招解决GitHub致命的下载速度(GitHub下载速度慢怎么办)

    通过码云来导入github,通过码云下载 第一步: 找一个你需要下载的GitHub项目 第二步: 复制链接 第三步: 打开码云,然后选择从GitHub导入 第四步: 复制刚才的连接,起个名字,点击导入 ...

  7. Java实现 蓝桥杯VIP 算法训练 调和数列

    问题描述 输入一个实数x,求最小的n使得,1/2+1/3+1/4+-+1/(n+1)>=x. 输入的实数x保证大于等于0.01,小于等于5.20,并且恰好有两位小数.你的程序要能够处理多组数据, ...

  8. java实现猜算式

    题目:猜算式 你一定还记得小学学习过的乘法计算过程,比如: x 15 ------ 273 ------ 请你观察如下的乘法算式 *** x *** -------- *** *** *** ---- ...

  9. Java实现Catenyms(并查集+dfs+欧拉回路)

    Description A catenym is a pair of words separated by a period such that the last letter of the firs ...

  10. springMVC 异常

    springMVC  异常 0.依赖(不只是本次案例所需) <?xml version="1.0" encoding="UTF-8"?> <p ...