1. 三体时间【算法赛】
问题描述
罗辑在担任面壁者期间,常常语出惊人。有一天,他对记者们宣布:“我的计划是,训练一群哈巴狗去征服宇宙!它们适应力超强,甚至能在三体行星上生存!”
记者们听得一头雾水:“三体行星?那里的时间系统和地球不一样啊,哈巴狗怎么适应?”
罗辑神秘一笑:“嘿嘿!我发明了一种时间转换装置,能把三体时间转换成地球时间。三体时间每过 1 个单位,相当于地球时间过了 26 个小时。我已经设置好装置,让哈巴狗们按照地球时间生活。”
他顿了顿,向一位记者提问:“考考你,如果三体时间过了 999 个单位,相当于地球时间过了几天几小时?”
为了简化计算,我们假设地球上每天都是 24 小时。
现在,请你帮助这位记者作答,将地球时间以 “d h” 的格式输出,其中 d 表示天数,h 表示小时数。例如,2 天 5 小时,输出 "2 5"。
输入格式
无
输出格式
输出一个字符串,格式为 "d h",其中 d 表示天数,h 表示小时数。
输入格式
无
输出格式
输出两个整数,格式为 "d h",其中 dd 表示天数,hh 表示小时数。
#include<bits/stdc++.h> using namespace std; int n, m; void solve() { n = 999*26; int a = n / 24; int b = n % 24; cout << a << " " << b ; } int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); solve(); return 0; }
2. 存储晶体【算法赛】
问题描述
威慑纪元 2230 年,人类联邦在与三体文明的对抗中,为了强化飞船的能源储备,决定收集能量晶体。飞船的储存空间呈矩形,边长分别为 aa 和 bb。对于一个能量晶体,只有当它的长度小于或等于存储空间的对角线长度时,它才能被安全地放入飞船中。
现在,人类联邦总共收集了 nn 个能量晶体。你的任务是判断每根能量晶体是否可以放入飞船。
输入格式
第一行包含两个整数 aa 和 bb(1≤b≤a≤1031≤b≤a≤103),表示飞船储存空间的长和宽。
接下来一行包含一个整数 nn(1≤n≤1031≤n≤103),表示能量晶体的数量。
再接下来 nn 行,每行包含一个整数 cc(1≤c≤1041≤c≤104),表示每根能量晶体的长度。
输出格式
对于每根能量晶体,输出一行:
- 如果该晶体可以放入,输出
YES
。- 如果该晶体不能放入,输出
NO
。样例输入
10 10 3 5 10 20
样例输出
YES YES NO
#include<bits/stdc++.h> using namespace std; int n, m; void solve() { int a, b; cin >> a >> b; double s = sqrt(a * a + b * b); cin >> n; for (int i = 1;i <= n;i++) { int k; cin >> k; if (k <= s) { cout << "YES" << endl; } else { cout << "NO" << endl; } } } int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); solve(); return 0; }
3. 屏蔽信号【算法赛】
问题描述
在与三体文明的对抗中,人类联邦探测到了两个重要的信号源,分别用非负整数 aa 和 bb 来表示。
为了抵御三体舰队的入侵,科学家们制定出一项关键策略——屏蔽信号,目标是要让 aa、bb 这两个信号源其中之一的数值归零。 在实施屏蔽操作时,有着一套既定规则:每次操作,科学家们需要先对比两个信号源的数值大小,然后用较大的那个数减去较小的数,得出差值之后,再把原本较大的那个数替换成这个差值。就这样反复操作,一轮一轮进行下去。
现在,请你来帮忙计算一下,按照这样的操作方式,要想实现将两个信号源之中任意一个变为零,所需要进行的最少操作次数是多少呢?
输入格式
第一行包含一个整数 tt (1≤t≤1031≤t≤103),表示测试数据的数量。
接下来的 tt 行,每行包含两个非负整数 aa 和 bb (0≤a,b≤1090≤a,b≤109),表示两个关键的信号源。
输出格式
对于每组测试数据,输出一个整数,表示将其中一个信号源变为零所需的最小操作次数,每个结果占一行。
样例输入
3 0 3 2 5 3 6
样例输出
0 4 2
#include<bits/stdc++.h> using namespace std; int n, m; void solve() { cin >> n >> m; int cnt = 0; while (n && m) { if (n > m) { swap(n, m); } int k = m / n; int q = m % n; cnt += k; m = q; } cout << cnt << endl; } int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); int t; cin >> t; while (t--) { solve(); } return 0; }
4. 掩体计划【算法赛】
问题描述
危机纪元 2211 年,由罗辑领导的雪地工程正式进入部署,雪地工程中布置了大量的核弹,整个工程由信号中转站和起爆装置构成,形成了一棵具有 nn 个点 n−1n−1 条边的有根树,11 号点为根节点,树边为 (ui,vi)(ui,vi) 。
起爆装置为度为 11 并且不是根的节点,其余节点为信号中转站,预先在 mm 个起爆装置上面布置有核弹,为了引爆核弹,会在 11 号节点施加一个引爆信号,在信号中转站上,该信号会随机向某一个子节点传输,为了避免核弹不被引爆,你可以在信号中转站上面安装控制器,使得引爆信号只会往指定的子节点传输,为了减少开销,你能帮帮罗辑计算最少需要安装的控制器数量吗?
输入格式
第 11 行包含一个正整数 nn(2≤ n ≤ 1052≤ n ≤ 105),表示树点的数量。
第 2∼n+12∼n+1 行每行包含 22 个正整数 ui,viui,vi(1≤ui,vi≤n1≤ui,vi≤n),分别表示树边的两个端点。
接下来 11 行包含一个正整数 mm (1≤ m ≤1≤ m ≤ 叶子数量) ,表示含有核弹的起爆装置的数量。
再接下来 11 行包含 mm 个整数 , 表示具有核弹起爆装置的节点编号。
输出格式
输出一个数字,表示需要放置的最小控制器数量。
样例输入
5 1 2 1 3 1 4 2 5 2 4 5
样例输出
1
我感觉这个题有点问题,正解应该不是这么简单的。。不知道有没有人和我同感
#include<bits/stdc++.h> using namespace std; const int N = 100010; int h[N], e[N], ne[N], idx; int n, m; int cnt[N]; bool st[N]; void bfs() { queue<int> q; q.push(1); cnt[1] = 1; while (q.size()) { int t = q.front(); q.pop(); for (int i = h[t];~i;i = ne[i]) { int j = e[i]; bool flag = 1; if (h[j] == -1) { flag = 0; } else if (ne[h[j]] == -1) { flag = 0; } if (flag) { cnt[j] = cnt[t] + 1; } else { cnt[j] = cnt[t]; } q.push(j); } } } void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx++; } void solve() { memset(h, -1, sizeof h); cin >> n; for (int i = 1; i < n; i++) { int a, b; cin >> a >> b; add(a, b); } cin >> m; for (int i = 1; i <= m; i++) { int x; cin >> x; st[x] = true; } bfs(); int ans = 0x3f3f3f3f; for (int i = 1;i <= n;i++) { if (st[i]) { //cout << cnt[i] << endl; ans = min(ans, cnt[i]); } } cout << ans; } int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); solve(); return 0; }
5. 智商检测【算法赛】
问题描述
威慑纪元 2275 年,人类联邦选出来新的执剑人程心,在黑暗森林的另一角,三体舰队首席执行官为了检测新执剑人的智商,通过具象扫描仪,扫描出了程心的精神模型,并且向执剑人提出了这样的问题:
给一个长度为 nn 的数组,要求删除恰好 kk 个数字,使得数组剩余数字的的 gcdgcd 最大。
那么,最大的 gcdgcd 会是多少呢?
输入格式
第 11 行包含两个正整数 n,kn,k(2≤n≤1052≤n≤105,1≤k≤min(n−1,102)1≤k≤min(n−1,102)),分别表示数组的长度和需要删除的数字的数量。
第 22 行包含 nn 个整数 a1,a2,⋯,an−1,ana1,a2,⋯,an−1,an(1≤ai≤1091≤ai≤109),分别表示数组中的 nn 个数字。
保证 aiai 是由随机数据 cici(随机生成的数值)乘以一个系数(系数的取值范围在 1∼1051∼105)所得。
输出格式
输出一个数字,表示删除恰好 kk 个数字之后的最大 gcdgcd。
样例输入
6 2 2 4 5 3 8 10
样例输出
2
题目埋坑了,想了很久,前后缀都试了,甚至想dp解,就是没想到题目埋坑了,这可以暴力解。
#include<bits/stdc++.h> using namespace std; const int N = 100010; int a[N]; int n, k; int ans; void solve() { cin >> n >> k; for (int i = 1;i <= n;i++) { cin >> a[i]; } for (int i = 1;i <= 100000;i++) { int cnt = 0; for (int j = 1;j <= n;j++) { if (a[j] % i ) { cnt++; } if (cnt > k) { break; } } if (cnt <= k) { ans = max(ans, i); } } cout << ans; } int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); solve(); return 0; }
6. 高能粒子【算法赛】
问题描述
威慑纪元 2233 年,人类地球联邦为了突破质子科技封锁,决定在太阳系的黄道平面上建造大量高能粒子对撞机,与普通高能粒子对撞机不同的是,可以将黄道平面抽象为一个二维平面。
一共有 nn 个 αα 高能粒子和 mm 个 ββ 高能粒子,αα 高能粒子的运动轨迹可以被描述为直线 yi=ai×xi+biyi=ai×xi+bi,ββ 高能粒子的运动轨迹可以被描述为直线 x=cix=ci。
因为越靠近对撞中心的粒子,其被质子干扰的程度越低,所以为了获得最准确的数据,我们需要选取一个合适的 ββ 粒子的运动轨迹,使得其与 αα 粒子运动轨迹的交点的 yy 值的中位数最大。
输入格式
输入第 11 行包含一个正整数 nn(1≤n≤1051≤n≤105),表示 αα 粒子的数量,保证 nn 为奇数。
第 2∼n+12∼n+1 行每行包含 22 个正整数 ai,biai,bi (−109≤ai,bi≤109−109≤ai,bi≤109),分别表示 αα 高能粒子的直线轨迹方程的两个参数。
接下来 11 行包含一个正整数 mm(1≤m≤5×1051≤m≤5×105),表示 ββ 粒子的数量。
再接下来 11 行包含 mm 个整数,表示 ββ 粒子的轨迹方程的参数 c1,c2,...,cmc1,c2,...,cm(1≤ci≤1091≤ci≤109)。
保证 αα 粒子的运动轨迹两两不同,ββ 粒子的运动轨迹两两不同。
输出格式
输出两个数字,表示选择的 ββ 粒子的下标编号 idid 和最大化的中位数。
下标编号 idid 从 11 开始。
样例输入
5 2 4 -2 1 4 5 -1 3 -2 -4 4 -3 3 2 -1
样例输出
1 2
样例解释
第 11 个 ββ 粒子的运动轨迹与 αα 粒子相交了 55 个点,对应的 yy 值分别为 −2,7,−7,6,2−2,7,−7,6,2,中位数为 22 。
这题初看没思路,但是看了一个老哥的题解,感觉很哇塞,中位数必然是递增,递减,或者是先减后增。画几条线就很直观。
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1000005; ll ax[N]; ll ay[N]; struct node{ ll x; ll posi; }b[N]; bool cmp(node a,node b){ return a.x<b.x; } ll t[N]; int main(){ int n;scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%lld %lld",&ax[i],&ay[i]); } int m;scanf("%d",&m); for(int i=1;i<=m;i++){ scanf("%lld",&b[i].x); b[i].posi=i; } sort(b+1,b+1+m,cmp); for(int i=1;i<=n;i++){ t[i]=ax[i]*b[1].x+ay[i]; } sort(t+1,t+1+n); ll ans1=t[(n+1)/2]; for(int i=1;i<=n;i++){ t[i]=ax[i]*b[m].x+ay[i]; } sort(t+1,t+1+n); ll ans2=t[(n+1)/2]; if(ans1>ans2){ printf("%lld ",b[1].posi); printf("%lld",ans1); }else{ printf("%lld ",b[m].posi); printf("%lld",ans2); } return 0; }