2025-暑期训练二
A
核心:使用set
存储所有相邻字符对,自动去重。
B
错误原解:只想简单的开一个,额外的c数组用来 找原来的索引,但往下做可以发现行不通
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
long long a[N],b[N],c[N];
void solve(){bool mark[N]={0}; //保证每次调用函数mark数组都重置为0int n,k;cin>>n>>k;for(int i=0;i<n;i++){cin>>a[i];c[i]=a[i];}for(int i=0;i<n;i++){cin>>b[i];}sort(a,a+n);sort(b,b+n);for(int i=0;i<n;i++){for(int j=0;j<n;j++){if(c[i]==a[j]&&!mark[j]&&i!=(n-1)){ //如果数组中存在相同元素,那么此时会直接把所有符合c[i]==a[j]cout<<b[j]<<" "; //条件所对应的b[j]一次性全部打印出来,造成第二样例出现多余的数mark[j]=1;}if(c[i]==a[j]&&!mark[j]&&i==(n-1)) cout<<b[j]<<endl;}}
}
int main(){int t;cin>>t;while(t--)solve();return 0;
}
正解:利用pair存储预测温度及其原始索引
核心逻辑分析
1. 数据结构设计:
vector<pair<int, int>> a
:存储预测温度及其原始索引,用于在排序后仍能追踪每个温度的原始位置。vector<int> b
:存储实际温度,后续需要排序。vector<int> ans
:存储最终结果,按原始索引顺序排列。
2. 排序策略:
- 对
b
排序:将实际温度按升序排列。 - 对
a
排序:按预测温度值升序排列,同时保留原始索引。
3. 匹配逻辑:
- 由于题目保证存在解,排序后的
a
和b
可以按顺序一一匹配。即排序后的第i
个预测温度对应排序后的第i
个实际温度。 - 通过
a[i].second
获取预测温度的原始索引,将对应的实际温度b[i]
放入结果数组ans
的正确位置。
陌生知识点
1.
for (auto& i : b) {cin >> i;
}
auto& i
:声明一个引用变量i
,类型由编译器自动推导(auto
)。使用引用(&
)允许直接修改容器中的元素。b
:要遍历的容器(如vector
、array
、string
等)。- 循环体:对容器中的每个元素执行的操作。
上述代码等价于:
for (int i = 0; i < b.size(); i++) {cin >> b[i];
}
2.pair<int, int> a(n)
的含义
- 创建单个
pair
:这行代码创建了一个名为a
的pair
对象,而非数组。 - 初始化参数:
n
被用作pair
的第一个元素(first
)的初始值,第二个元素(second
)默认初始化为0
。
等价于:pair<int, int> a = {n, 0}; // 第一个元素为n,第二个元素为0
vector<pair<int, int>> a(n);
是 C++ 中声明并初始化一个动态数组的语句,创建了一个名为 a
的 vector
容器,它可以存储 n
个 pair
对象。
语法分解
vector
:C++ 标准库中的动态数组容器,可自动调整大小。pair<int, int>
:存储两个int
类型元素的组合,称为 “键值对”。a(n)
:创建名为a
的向量,初始大小为n
,每个元素都是pair<int, int>
类型,默认初始化为{0, 0}
。- 排序时,默认会按照
pair
的第一个元素(first
)升序排列。
总结
pair<int, int> a(n)
:创建 单个pair
,用于存储 一组键值对。vector<pair<int, int>> a(n)
:创建 动态数组,用于存储 多组键值对。
代码:
#include<bits/stdc++.h>
using namespace std;
void solve(){int n,k;cin>>n>>k;vector<int>b(n),result(n);vector<pair<int,int>>a(n);for(int i=0;i<n;i++){cin>>a[i].first;a[i].second=i;}for(auto &i:b)cin>>i;sort(b.begin(),b.end());sort(a.begin(),a.end());for(int i=0;i<n;i++){result[a[i].second]=b[i];// 将b[i]放入result中对应a[i]的原始位置}for(int i=0;i<n;i++){cout<<result[i]<<" ";}cout<<endl;
}
int main(){int t;cin>>t;while(t--){solve();}return 0;
}
C
错误原解:求最小值时,必须初始胡为足够大的值,比如1e18;
#include<bits/stdc++.h>
using namespace std;
const int N=200005;
int a[N];
void solve(){int n;cin>>n;long long mn=200005; //mn 初始化为 200005,若输入的所有元素都大于这个值,for(int i=0;i<n;i++){ //mn 不会被正确更新。应初始化为足够大的值(如 1e18)或第一个元素。cin>>a[i];if(a[i]<mn) mn=a[i];} bool o=1,q=1;for(int i=0;i<n;i++){if(a[i]%2==0)q=0;if(a[i]%2==1)o=0;}if(o||q){cout<<"YES"<<endl;return;}if(mn%2==0){for(int i=0;i<n;i++){if(a[i]%2==1){cout<<"NO"<<endl;return;}}}cout<<"YES"<<endl;
}
int main(){int t;cin>>t;while(t--) solve();return 0;
}
正解:
#include<bits/stdc++.h>
using namespace std;
const int N=200005;
int a[N];
void solve(){int n;cin>>n;long long mn=1e18; //改数即可for(int i=0;i<n;i++){cin>>a[i];if(a[i]<mn) mn=a[i];} bool o=1,q=1;for(int i=0;i<n;i++){if(a[i]%2==0)q=0;if(a[i]%2==1)o=0;}if(o||q){cout<<"YES"<<endl;return;}if(mn%2==0){for(int i=0;i<n;i++){if(a[i]%2==1){cout<<"NO"<<endl;return;}}}cout<<"YES"<<endl;
}
int main(){int t;cin>>t;while(t--) solve();return 0;
}
核心思路:
- 若最小元素为奇数,则所有元素都要调整为奇数且奇数-奇数,偶数-奇数都等于奇数,因此,只要最小元素是奇数,就输出YES。
- 若最小元素为偶数,则所有元素都要调整为偶数,只有偶数-偶数=偶数,因此一旦出现奇数就输出NO。
因此这样写代码更简洁,因为已经包含了全奇全偶的情况了
简洁代码:
#include<bits/stdc++.h>
using namespace std; void solve() { int n; cin >> n; vector<int> a(n); for (int i = 0; i < n; i++)cin >> a[i]; sort(a.begin(), a.end()); // 对数组a进行升序排序if (a[0] % 2 == 1) { // 检查最小元素是否为奇数cout << "YES" << endl; return; // 结束当前测试用例的处理}for(int num : a) { // 遍历排序后的数组aif (num % 2 == 1) { // 检查是否存在奇数元素cout << "NO" << endl; return; // 结束当前测试用例的处理}}cout<<"YES"<<endl; // 若所有元素都是偶数,输出YES
}int main() { int t; cin >> t; while(t--) solve();return 0;
}