A
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define lson (rt << 1)
#define rson ((rt << 1) | 1)
#define pill pair<int, int>
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e5 + 10;
const LL INF = 1e18 + 10;
LL a[qq];
int main(){
int n; scanf("%d", &n);
LL sum = 0;
LL x;
for(int i = 0; i < n; ++i) {
scanf("%lld", &x);
sum += x;
}
for(int i = 0; i < n; ++i) {
scanf("%lld", a + i);
}
sort(a, a + n);
if(sum > a[n - 1] + a[n - 2]) {
puts("NO");
} else {
puts("YES");
}
return 0;
}
B
倒着遍历维护每次能杀到最前面的id
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define lson (rt << 1)
#define rson ((rt << 1) | 1)
#define pill pair<int, int>
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e6 + 10;
const LL INF = 1e18 + 10;
int num[qq];
int main(){
int n; scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%d", num + i);
}
int maxn = n + 1;
int ans = n;
for(int i = n; i >= 1; --i) {
if(maxn <= i) ans--;
maxn = min(maxn, i - num[i]);
}
printf("%d\n", ans);
return 0;
}
C
题意:每次可以求一下相邻两个数的gcd并用这gcd代替这两个数中的其中一个,问最后序列全部为1最少操作多少次,不可以就输出-1
思路:很明显如果求出整个序列的gcd > 1的话肯定是-1, 如果序列中存在1的情况的话只需要n - (1的个数)就是操作数了,剩下情况就n^2暴力枚举求出每一段的gcd,求出最小一段的gcd = 1的然后答案就是这个长度 + n - 1
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <utility>
#include <bitset>
using namespace std;
#define LL long long
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define lson (rt << 1)
#define rson ((rt << 1) | 1)
#define pill pair<int, int>
#define mst(a, b) memset(a, b, sizeof a)
#define REP(i, x, n) for(int i = x; i <= n; ++i)
const int MOD = 1e9 + 7;
const int qq = 1e5 + 10;
const int INF = 1e9 + 10;
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
int num[2005];
int main(){
int n; scanf("%d", &n);
bool f = false;
int tmp;
for(int i = 1; i <= n; ++i) {
scanf("%d", num + i);
if(num[i] == 1) f = true;
if(i == 1) tmp = num[i];
else tmp = gcd(tmp, num[i]);
}
if(f) {
int cnt = 0;
for(int i = 1; i <= n; ++i) {
if(num[i] == 1) cnt++;
}
printf("%d\n", n - cnt);
return 0;
}
if(tmp > 1) {
printf("-1\n");
return 0;
}
int minx = INF;
for(int j, i = 2; i <= n; ++i) {
int x = num[i - 1];
for(j = i; j <= n; ++j) {
x = gcd(x, num[j]);
if(x == 1) break;
}
if(x == 1) {
minx = min(minx, j - (i - 1));
}
}
printf("%d\n", minx + (n - 1));
return 0;
}
D
题意:给出序列a,将a序列重排一下成为b序列,使得a序列的所有非空子序列和不等于b序列的子序列和
思路:题目说了所有数都不相同,那么我们可以构造b序列中的数都比其对应a序列中的数恰好大一点点,
比如 1 2 3 4
2 3 4 1
这里除了a序列中最大的4对应b序列的1意外其他的b序列中对应的都比a序列要大
我们可以这样分析,选出的子序列假设a中的和是x1, 那么a序列中未被选中的和是x2,b序列中被选中的子序列和是y1,为被选中的和是y2
可以知道 x1 + x2 = y1 + y2
如果x1中不包含a序列的最大值,那么可以知道 x1 < y1
如果x1中包含a序列的最大值,那么可以知道 x2 < y2 由最初的等式就知道 x1 > y1
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define fi first
#define se second
#define mk make_pair
#define mst(a, b) memset(a, b, sizeof a)
const int qq = 1e5 + 10;
const int MOD = 1e9 + 7;
const int INF = 1e9 + 10;
int a[qq], b[qq], c[qq];
map<int, int> mp, rk;
int main() {
int n; scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%d", a + i);
c[i] = a[i];
}
sort(c + 1, c + 1 + n);
for(int i = 1; i <= n; ++i) {
rk[c[i]] = i;
mp[i] = c[i];
}
for(int i = 1; i <= n; ++i) {
int tmp = rk[a[i]];
b[i] = mp[(tmp == n ? 1 : tmp + 1)];
}
for(int i = 1; i <= n; ++i) {
printf("%d ", b[i]);
}
puts("");
return 0;
}