CF EDU7
- [A Infinite Sequence](http://codeforces.com/contest/622/problem/A)
- 思路
- 代码
- [B The Time](http://codeforces.com/contest/622/problem/B)
- 思路
- 代码
- [C Not Equal on a Segment](http://codeforces.com/contest/622/problem/C)
- 思路
- 代码
- [D Optimal Number Permutation](http://codeforces.com/contest/622/problem/D)
- 思路
- 代码
- [E Ants in Leaves](http://codeforces.com/contest/622/problem/E)
- 来一发机房大佬题解
A Infinite Sequence
思路
玄学做法
m ∗ ( m + 1 ) 2 ≤ n \frac{m * (m+1)}{2} \leq n 2m∗(m+1)≤n, m指1到m的和、
那n一定属于1到m+1这一个循环。
找到m, 将n减去 m ∗ ( m + 1 ) 2 \frac{m * (m+1)}{2} 2m∗(m+1)即可。
注意:如果减去后等于0, 说明n正好是m。
优化:找m缩小枚举范围
代码
#include<bits/stdc++.h>using namespace std;long long n;
long long now;
int main()
{cin >> n;for(long long i = (int)(sqrt(2 * n)) + 1; i >= 1; i--){if(i * (i + 1) <= 2 * n){now = i;break;}}//cout << now << endl;n = n - (now * (now+1) / 2);if(n == 0){n = now;}cout << n << endl;return 0;
}
大佬蒙逼玄学做法
模拟
对于每一列
它每次都比上一列多一个n
看这儿
int main(){ LL n; cin>>n; LL now=1; while(n>now){ n-=now; now++; } cout<<n; return 0;}
B The Time
思路
模拟。
把小时和分钟分离
先在分钟上加上要加的数。
然后在分钟上%60;
接着, 再在小时上+(分钟/60)
最后注意输出
代码
#include<bits/stdc++.h>using namespace std;int h;
int m;
char s[10];
int dmin;
int main()
{scanf("%s", s+1);h = (s[1] - '0') * 10 + (s[2] - '0');m = (s[4] - '0') * 10 + (s[5] - '0');cin >> dmin;m += dmin;int dh = m / 60;m %= 60;h += dh;h %= 24;if(h < 10){cout << '0' << h;}else{cout << h;}cout << ':';if(m < 10){cout << '0' << m;}else{cout << m;}return 0;
}
大佬全化成分钟在做的。
#include<bits/stdc++.h>using namespace std;using int64 = long long;
const int mod = 1e9 + 7;
const int inf = (1 << 30) - 1;
const int64 infll = (1LL << 61) - 1;struct IoSetup {IoSetup() {cin.tie(nullptr);ios::sync_with_stdio(false);cout << fixed << setprecision(10);cerr << fixed << setprecision(10);}
} iosetup;template< typename T >
ostream &operator<<(ostream &os, const vector< T > &v) {for(int i = 0; i < (int) v.size(); i++) {os << v[i] << (i + 1 != v.size() ? " " : "");}return os;
}template< typename T >
istream &operator>>(istream &is, vector< T > &v) {for(T &in : v) is >> in;return is;
}template< typename T1, typename T2 >
inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }template< typename T1, typename T2 >
inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }template< typename T = int64 >
vector< T > make_v(size_t a) {return vector< T >(a);
}template< typename T, typename... Ts >
auto make_v(size_t a, Ts... ts) {return vector< decltype(make_v< T >(ts...)) >(a, make_v< T >(ts...));
}template< typename T, typename V >
typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) {t = v;
}template< typename T, typename V >
typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) {for(auto &e : t) fill_v(e, v);
}int main() {int h, m, v;scanf("%d:%d", &h, &m);scanf("%d", &v);int t = h * 60 + m;t += v;t %= 24*60;printf("%02d:%02d\n", t / 60, t % 60);
}
C Not Equal on a Segment
思路
找每个数左边第一个与他不相等的数。设p[x] 为左边第一个与a[x]不相等的数的下标。
显然, 如果a[i] != a[i-1], 则p[i] = i-1; 否则p[i] = p[i-1];
对于每一个询问[l,r] (x), 如果p[r] < l 同时 a[r] == x 的话, 区间里全为x输出-1,
否则:
1.a[r] == x 输出p[r];
2 a[r] != x 输出r
代码
#include<bits/stdc++.h>using namespace std;int n, m;
int a[200010];
int p[200010];
int main()
{cin >> n >> m;for(int i = 1; i <= n; i++){scanf("%d", &a[i]);if(a[i] == a[i-1]){p[i] = p[i-1];}else{p[i] = i-1;}}while(m--){int l, r, x;scanf("%d %d %d", &l, &r, &x);if(p[r] < l && a[r] == x){printf("-1\n");}else{if(a[r] != x){printf("%d\n", r);}else{printf("%d\n", p[r]);}}}return 0;
}
D Optimal Number Permutation
思路
显然, 要让他最小的话, 我们首先要让每一项都尽可能小。
这是一个单项式。。。
第一个因式我们好像没法改变。。。
考虑第二个因式: ∣ d i + i − n ∣ |d_i + i - n| ∣di+i−n∣
因为要让这个单项式尽可能小, 还是那句话, 每一项都尽可能小(最好为0)
所以, 我们可以尝试让第二个因式为0
得到 d i = n − i d_i = n - i di=n−i
所以, 很轻松得到了同一个数i在这个数列中两个位置差应为n - i;
考虑构造。
举一个例子
11 22 33 44 55
4 3 2 1 0
由于1距离为4, 所以中间应有3个数。
我们可以添3, 因为ta距离为2, 正好能镶进1中间。
还剩了一个位置, 我们可以填距离为0的5(因为它对整个序列没有影响)
这样前5个位置就填满了。
然后, 在往后填2, 距离为3, 中间有2个空, 正好可以填距离为1的4.
最后在填剩下一个5.
答案为: 1353124425
因此, 我们发现规律:奇数偶数分别填成两个序列拼一块在接一个n就是答案
代码
#include<bits/stdc++.h>using namespace std;int n;
//bool vis[500010];
int m;
int main()
{cin >> n;for(int i = 1; i <= n; i += 2){cout << i << " ";}/*if(n % 2 == 1){cout << n;}*/m = n-1;if((n-1) % 2 == 0){m = n-2;}for(int i = m; i >= 1; i-=2){cout << i << " ";}for(int i = 2; i <= n; i += 2){cout << i << " ";}/*if(n % 2 == 0){cout << n;}*/m = n-1;if((n-1) % 2 == 1){m = n-2;}for(int i = m; i >= 1; i-=2){cout << i << " ";}cout << n << endl;return 0;
}