ABC 409
A:水
B:注意考虑清楚有多种情况,注意不是让你在A数组里找元素而是在1-N里找!!!
C:注意L一定要是3的倍数否则必不可能有等边三角形
#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<cstring>
#include<algorithm>
#include <sstream>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 500005;
int N, D, R,fk,L,fg,pg1,pg2;
long long ans;
long long OL[MAXN];
bool cmp(int a, int b) {
return a > b;
}
int main() {
int tp = 0;
fk = 0;
OL[fk] = 1;
scanf("%d %d", &N,&L);
for(int i=1;i<N;i++){
scanf("%d",&tp);
fk = (fk + tp)%L;
OL[fk]++;
}
if(L%3!=0)
{
cout<<"0\n";
return 0;
}
ans = 0;
pg1 = L/3;
pg2 = pg1*2;
for(int i=0;i<pg1;i++){
if(OL[i]&&OL[i+pg1]&&OL[i+pg2]){
ans += OL[i] * OL[i+pg1] * OL[i+pg2];
}
}
printf("%lld",ans);
return 0;
}
D:要求你执行一次把任意字母移动到后面任意位置使得总字典序最小,自然从第一位开始尝试能否往后移,而只要当前字母大于等于后面字母就可以往后移,第一个可以往后移的即是答案。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 200005;
char S[MAXN], tmp[MAXN], ans[MAXN];
int T, N,fk;
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d",&N);
scanf("%s", S);
int gg = 0;fk = 0;
for(int i = 1;i < N;i++){
if(S[gg] < S[i]){
gg = i;
}else if(S[gg] > S[i]){
fk = i;
while(S[gg] >= S[fk]){
fk++;
if(fk == N){
break;
}
}
break;
}
}
for(int i=0;i<N;i++){
if(i>=gg && i<fk - 1){
printf("%c",S[i+1]);
}else if(i == fk - 1){
printf("%c",S[gg]);
}else{
printf("%c",S[i]);
}
}
printf("\n");
}
return 0;
}
/*
3
5
snuke
7
atcoder
1
x
*/
E:采用后序遍历,对于叶节点来说,其归零电荷的方法只有转移电子进来或出去到父节点,而这代价是一样的,所以干脆直接给出到父节点即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 100005; // 树的最大节点数
int N;
int x[MAXN];
long long total_energy;
struct Edge {
int to;
int weight;
};
Edge edges[MAXN*2]; // 双向边
int head[MAXN], next_edge[MAXN*2], edge_count;
// 添加边
void add_edge(int u, int v, int w) {
edge_count++;
edges[edge_count] = {v, w};
next_edge[edge_count] = head[u];
head[u] = edge_count;
}
// 后序遍历计算每个子树的电荷总和,并累加边的贡献
void dfs(int u, int parent) {
for (int i = head[u]; i != -1; i = next_edge[i]) {
Edge& e = edges[i];
int v = e.to;
int w = e.weight;
if (v == parent) continue;
dfs(v, u);
int charge = abs(x[v]);
total_energy += (long long)charge * w;
x[u] += x[v];
}
}
int main() {
int u, v, w;
memset(head, -1, sizeof(head));
edge_count = 0;
total_energy = 0;
scanf("%d", &N);
// 读取每个顶点的电荷
for (int i = 1; i <= N; i++) {
scanf("%d", &x[i]);
}
// 读取树的边
for (int j = 1; j < N; j++) {
scanf("%d%d%d", &u, &v, &w);
add_edge(u, v, w);
add_edge(v, u, w);
}
// 从顶点1开始DFS
dfs(1, -1);
printf("%lld\n", total_energy);
return 0;
}