题解 | #所有题解#
至至子的等差中项
https://ac.nowcoder.com/acm/contest/38630/A
前言
嘿,我又回来了!!!!
1年没见牛客网,总有点小鸡冻!!!!!
这一年没怎么搞OI,我退步了不少,但也会做水题吧!!!
我不会说前4道题做了我一天的
开始讲题
T1 至至子的等差中项
挺简单啊的,相信大家都会把! 就是求一个等差中项了!!
我们知道,三个数是 a b b*2-a,至于为什么,自己思考吧!!
#include <bits/stdc++.h>
using namespace std;
int main() {
int x, y;
cin >> x >> y;
cout << 2 * y - x;
}
T2 至至子的按位与
哦??这不就一位一位算就完了??看代码吧
#include<iostream>
using namespace std;
typedef long long ll;
int main(){
ll a,b,x,y;
ll t=1;
ll ans=0;
cin>>a>>b;
for(int i=1;i<=63;i++){
if((a&1)==(b&1)) ans+=t;
a>>=1;
b>>=1;
t*=2;
}
cout<<ans;
return 0;
}
T3:至至子的斐波那契
咳咳咳,说起这道题,我满满的都是泪啊,快一年没搞OI了,lower_bound都不会用了!!
调了3个小时终于调过了样例,好不容易呀
不知道有没有跟我一样的人。。。。。。(我猜没有把)
以上为自己感慨。下面开始讲
先预处理斐波拉契数列(这个你总会吧??,虽然我想了10分钟才想出来这个办法)
然后找最近的数,也很简单的。
具体步骤:二分找到第一个大于等于x的数,这个数的前一个数和这个数就是可能的答案。(二分卡了半天,最后想起多年前我见到过一个lower_bound)
分别取min就好了(我在这里卡了半天)
#include <bits/stdc++.h>
using namespace std;
#define int long long
int a[1005], l;
signed main() {
a[1] = 1, a[2] = 1;
for (int i = 3; i <= 1001; i++) {
a[i] = a[i - 1] + a[i - 2];
if (a[i] > 1e18) break;
l = i;
}
int t, n;
cin >> t;
while (t--) {
cin >> n;
int id = lower_bound(a + 1, a + l + 1, n) - a;
int x = a[id], y = a[id - 1]; // x是这个数,y是前一个数,这两个才是可能的答案
if (abs(n - x) < abs(n - y)) cout << id << endl; // 分别输出,卡了我半天
else if (abs(n - x) > abs(n - y)) cout << id - 1 << endl;
else cout << id - 1 << endl;
// 这个情况就是abs(n-x)==abs(n-y)的情况,但是要输出编号最小的,所以id-1了
//(我在这里想了30分钟。。)
}
}
T4 至至子的鸿门宴
哎,这道题,想到了就很简单,没想到就完蛋了。
假如说你足够聪明,想到了两个人操作后的最终序列一定是 1 2 3 .. n
就可以了。因为肯定能构造出这种序列啊,最开始的序列是合法的。
于是能操作的次数就是 最开始序列和 。
然后操作次数定了,谁胜谁负就是博弈论了!!!
然后蒟蒻我不会博弈论,我就告诉大家我想了4个小时的一个结论:
如果能操作的次数是奇数,先手必胜,否则,后手必胜!
这个结论,无比重要,可以推广到所有博弈论问题!!!(不妨把它称为ojs结论)
献上我写了1个小时的代码:(毕竟快一年没搞OI)
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 6;
int n, a[N], res;
signed main() {
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i], res += a[i];
int t = (1 + n) * n / 2;
res -= t;
if (res % 2 == 1) puts("ZZZ");
else puts("SSZ");
}
总结一下:一年前,我的水平还算可以(CSP-J 90分,算高吧),但是现在连水题都要琢磨半天,我只能说我太难了。。。。题目出的真好,希望下次不要出了