总结: 这才是我理想中的div3
虽然WA了好几次,但是我可以刷锅给神志不清,题目思路也简单,不跟前几次一样瞅着看一个多小时还是看不懂这东西怎么处理的情况,啊,斯巴拉西得死。
ABCD都不难,A题题目巨长,太过分了。B题WA了两次,脑子不清醒啊,每次的标记f [a[i]]- -,我给放到if判断里面了,就这,样例居然过了,还WA test7,这就让我头大。C题双指针遍历就好。D题还是对我还是有难度,主要是分情况讨论我想的太慢了,第一次WA是因为情况分类有一类分错了,十分尴尬。
E题我只写了个前序遍历,嗯·· 然后T了,我个沙雕还在疑惑:怎么会T呢?询问次数*o(n)的dfs好么,嗯,大佬都是把距离转换成根节点到目标节点的距离算的,这样只要dfs一次,预处理根节点到所有节点的距离就好。但是这个代码···真的写的跟工程一样的···
F题受益匪浅,meet in middle的搜索技巧,第一次见,给大佬orz一个
A
#include <iostream>
using namespace std;
int main()
{
int n; cin>>n;
for(int i=0;i<n;i++){
int x; cin>>x;
if(x&1) cout<<x<<" ";
else cout<<x-1<<" ";
}
return 0;
}
B
#include <iostream>
#include <algorithm>
using namespace std;
int f[2005];
int a[2005],b[2005];
int main()
{
int n,k; cin>>n>>k;
for(int i=0;i<n;i++){
cin>>a[i];
b[i]=a[i];
}
sort(b,b+n);
reverse(b,b+n);
int sum=0;
for(int i=0;i<k;i++)
{
f[b[i]]++;
sum+=b[i];
}
cout<<sum<<endl;
int cnt=0,first=1;
a[n]=2001; f[2001]=1;
for(int i=0;i<=n;i++){
if(f[a[i]]){
f[a[i]]--;
if(first){cnt++; first=0; continue;}
cout<<cnt<<" ";
cnt=0;
}
cnt++;
}
//if(n-s) cout<<n-s<<endl;
return 0;
}
C
#include <iostream>
using namespace std;
typedef long long LL;
const int N=2e5+10;
LL sum[N],a[N];
int main()
{
int n; cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
int l=0,r=n+1;
LL s1=0,s2=0,ans;
while(l<r){
if(s1<s2){
s1+=a[++l];
}
else if(s1>s2){
s2+=a[--r];
}
else {
ans=s1;
s1+=a[++l];
}
}
cout<<ans<<endl;
return 0;
}
D
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
int n; cin>>n;
string x,y; cin>>x>>y;
int ans=0;
//int s[30];
//if(x==y || x==reverse(y)) {cout<<0<<endl; return 0;}
for(int i=0;i<n/2;i++){
char a=x[i],b=x[n-i-1],c=y[i],d=y[n-i-1];
if ((a==b&&c==d)||(a==c&&b==d)||(a==d&&b==c))
continue;
if(a==c || a==d ||b==c || b==d ||c==d) ans++;
else ans+=2;
}
if(n&1){
if(x[n/2]!=y[n/2]) ans++;
}
cout<<ans<<endl;
return 0;
}
E
#include <bits/stdc++.h>
using namespace std;
int n, q;
vector<vector<int>> tree;
int current_preorder;
vector<int> preorder, max_preorder;
vector<int> sorted_by_preorder;
void Dfs(int w) {
sorted_by_preorder[current_preorder] = w;
preorder[w] = current_preorder++;
for (int c : tree[w]) {
Dfs(c);
}
max_preorder[w] = current_preorder - 1;
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n >> q;
tree.resize(n);
for (int i = 1; i < n; i++) {
int p;
cin >> p;
p--;
tree[p].push_back(i);
}
preorder.resize(n);
max_preorder.resize(n);
sorted_by_preorder.resize(n);
current_preorder = 0;
Dfs(0);
for (int i = 0; i < q; i++) {
int u, k;
cin >> u >> k;
u--; k--;
k += preorder[u];
int answer = -1;
if (k <= max_preorder[u]) {
answer = sorted_by_preorder[k] + 1;
assert(1 <= answer and answer <= n);
}
cout << answer << '\n';
}
return 0;
}
F
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
map<long long, int> v[N][N];//相当于结构体v[x][y] 每一个节点包含 LL的异或结果 和 int的个数
//meet in middle的搜索技巧 学到了 NB
int n, m;
int half;
long long k;
long long a[N][N];
long long ans;
void calclf(int x, int y, long long val, int cnt) {//x y记录坐标 val记录异或值 cnt记录搜索的点的个数
val ^= a[x][y];//更新当前异或值
if (cnt == half) {
++v[x][y][val];
return;
}
if (x + 1 < n)
calclf(x + 1, y, val, cnt + 1);
if (y + 1 < m)
calclf(x, y + 1, val, cnt + 1);
}
void calcrg(int x, int y, long long val, int cnt) {//这个 稍微难一些
if (cnt == n + m - 2 - half) {
if (v[x][y][k ^ val])
ans += v[x][y][k ^ val];
return;
}
if (x > 0)
calcrg(x - 1, y, val ^ a[x][y], cnt + 1);
if (y > 0)
calcrg(x, y - 1, val ^ a[x][y], cnt + 1);
}
int main() {
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
cin >> n >> m >> k;
half = (n + m - 2) / 2;//设定搜索的最大长度 从(1,1)到(n,m)的一半
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cin >> a[i][j];
}
}
calclf(0, 0, 0, 0);//正着搜
calcrg(n - 1, m - 1, 0, 0);//倒着搜
cout << ans << endl;
return 0;
}