对输入数据的处理
在对题目进行分析时习惯性的想让输入的数据一直保持初始状态,再在其基础上做处理。但当最后需要的结果与输入数据的初始状态无特别关联时,直接对输入数据处理,而不在意对其改变,应当作为一种优先的思考方式。
直接更新数据
C-anon的私货_2024牛客寒假算法基础集训营5 (nowcoder.com)
#include<bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n;
cin>>n;
vector<long long> str(n);
for(int i=0;i<n;i++){
cin>>str[i];
}
long long ans=0;
ans+=str[0]-1;
str[0]=1;
int tr=0;
for(int i=1;i<n;i++){
tr=min(str[i-1],str[i])-1;
//cout<<tr<<" ";
ans+=tr;
str[i]-=tr;
}
ans+=str[n-1]-1;
cout<<ans;
return 0;
}
将位置变化转化为下标换算
当每次更新都要对整个数组操作而数组元素不变时,效率低,易超时,应转而考虑从下标入手,寻找规律
SMU Winter 2024 Round #4 (Div.2) - Virtual Judge (vjudge.net) I题
变化一次更新全数组TLE
#include<bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n,q;
cin>>n>>q;
vector<char> v(n);
for(int i=0;i<n;i++){
cin>>v[i];
}
while(q--){
int a,b;
cin>>a>>b;
if(a==1){
vector<char> vv(b);
for(int i=0;i<b;i++){
vv[b-1-i]=v.back();
v.pop_back();
}
v.insert(v.begin(),vv.begin(),vv.end());
}
else{
cout<<v[b-1]<<endl;
}
}
return 0;
}
位置变换转下标运算AC
#include<bits/stdc++.h>
using namespace std;
int main() {
int n,q,js=0;
cin>>n>>q;
vector<char> v(n+1);
for(int i=1;i<=n;i++){
cin>>v[i];
}
while(q--){
int a,b;
cin>>a>>b;
if(a==1){
js+=b;
js%=n;
}
else{
int x=(b+(n-js))%n;
if(x==0) x=n;
cout<<v[x]<<endl;
}
}
return 0;
}
布尔和哈希
遇到这类问题总习惯性想用布尔,但容易想太复杂,哈希要灵活许多,适合与元素情况不确定时的统计,而布尔更适合与数目固定,元素情况统一的统计
布尔:SMU Winter 2024 Round #4 (Div.2) - Virtual Judge (vjudge.net) E题
哈希:SMU Winter 2024 Round #4 (Div.2) - Virtual Judge (vjudge.net) C题
关于题目数据量级
数据太大
当题目中需要的一些数据太大运算会出现误差时,若运算所需的大的数据不多可以算好了直接写在代码中存在数组里
第五次选拔赛 - Virtual Judge (vjudge.net) J题
#include<bits/stdc++.h>
using namespace std;
unsigned long long p26[]={1,26,676,
17576,456976,11881376,
308915776,8031810176,208827064576,
5429503678976,141167095653376,3670344486987776};//26的0-11次幂
int main(){
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
string s;
cin>>s;
unsigned long long n=s.size();
unsigned long long x=0;
for(int i=0;i<n;i++){
x+=((int)s[i]-64)*p26[n-i-1];
}
cout<<x<<endl;
return 0;
}
勇敢暴力
当预判运算次数在10^9以内(甚至左右)时(1s标准),优化到觉得足够时勇敢暴力试试,想太多可能白想
第五次选拔赛 - Virtual Judge (vjudge.net) L题(最开始想着循环3次估计会到10^9次运算了不敢交,硬想了很久还是直接交了)
数据不大但是写出来TLE,必须转换思路
第五次选拔赛 - Virtual Judge (vjudge.net) E题
最开始老在纠结于取绝对值,后来转换思路发现:一个数减去别的数的次数就是看其是第几大的数
于是转向通过 排序+前缀和 解决
#include<bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int n;
cin>>n;
vector<long long> vec(n);
for(int i=0;i<n;i++){
cin>>vec[i];
}
sort(vec.begin(),vec.end());
vector<long long> vv(n);
vv[0]=vec[0];
for(int i=1;i<n;i++){
vv[i]+=vv[i-1]+vec[i];
}
unsigned long long ans=0;
for(int i=n-1;i>0;i--){
ans+=vec[i]*i-vv[i-1];
}
cout<<ans;
return 0;
}
上面Round #4 I题也是如此
数据乘以一个倍数从而避免使用浮点数比大小
SMU Winter 2024 Round #4 (Div.2) - Virtual Judge (vjudge.net) L题
题目中有 除100 的运算,直接按题目式子写会WA,将比较的对象扩大100倍,避免使用浮点数后AC