Atcoder Beginner Contest 417 A-E
平时只有写了A-E才来发题解的,然后发现自己很久没有发ABC的题解了(TT)

为了庆祝我的rating起死回生,来水题解了。
不过感觉ABC最近好像变难了
AB
#include<bits/stdc++.h>
#define usetime() (double)clock () / CLOCKS_PER_SEC * 1000.0
using namespace std;
typedef long long LL;
void read(int& x){
char c;
bool f=0;
while((c=getchar())<48) f|=(c==45);
x=c-48;
while((c=getchar())>47) x=x*10+c-48;
x=(f ? -x : x);
return;
}
int n,l,r;
int main(){
read(n),read(l),read(r);
string s;
cin>>s;
for(int i=l;i<=n-r-1;i++) cout<<s[i];
return 0;
}
//^o^
#include<bits/stdc++.h>
#define usetime() (double)clock () / CLOCKS_PER_SEC * 1000.0
using namespace std;
typedef long long LL;
const int maxn=1e6+5;
void read(int& x){
char c;
bool f=0;
while((c=getchar())<48) f|=(c==45);
x=c-48;
while((c=getchar())>47) x=x*10+c-48;
x=(f ? -x : x);
return;
}
multiset<int> st;
int n,m;
int main(){
read(n),read(m);
for(int i=1;i<=n;i++){
int in;
read(in);
st.insert(in);
}
for(int i=1;i<=m;i++){
int in;
read(in);
if(st.find(in)!=st.end()) st.erase(st.find(in));
}
for(auto i=st.begin();i!=st.end();i++){
cout<<*i<<' ';
}
return 0;
}
//^o^
用STL提供的multiset搞就可以了
C
等式变形
j-i=a[i]+a[j] -> j-a[j]=a[i]+i
然后建个桶就可以做啦
#include<bits/stdc++.h>
#define usetime() (double)clock () / CLOCKS_PER_SEC * 1000.0
using namespace std;
typedef long long LL;
const int maxn=2e5+5;
void read(int& x){
char c;
bool f=0;
while((c=getchar())<48) f|=(c==45);
x=c-48;
while((c=getchar())>47) x=x*10+c-48;
x=(f ? -x : x);
return;
}
int a[maxn];
int t[maxn<<1];
int n;
int main(){
read(n);
for(int i=1;i<=n;i++) read(a[i]);
LL ans=0;
for(int i=n;i>=1;i--){
ans+=t[a[i]+i];
if(i-a[i]>0) ++t[i-a[i]];
}
cout<<ans<<endl;
return 0;
}
//^o^
D
(已补)
赛时想的是记录当开始时初始值在不同区间时所对的答案
对于每一次收到礼物,会产生三个区间
1.p[i]>=now 对于区间0到p[i]增加一个a[i]
2.p[i]<now&&now>=b[i] 对于区间max(p[i]+1,b[i])到inf减去一个b[i]
3.p[i]<now&&now<b[i] 对于区间p[i]+1到b[i]-1设为0
但是这么做会让程序十分复杂赛时没有调出来,而且对于初始值极大的问题就束手无策了
考虑动态规划,注意数据范围,所有涉及心情变化的值均小于等于500
那么可以说明,当一个1000以内的心情加入运算时,这个值一定会持续保留在1000以内
设计dp[i][j]表示第i次运算前,当前心情为j,最后会达到的心情
对于初始值极大的问题,保留dp的第一维(也就是第i次运算时),二分需要减去多少才会达到1000以内
然后在dp的当前次运算中取答案即可,时间复杂度为O(mn + q log n)
#include<bits/stdc++.h>
#define usetime() (double)clock () / CLOCKS_PER_SEC * 1000.0
using namespace std;
typedef long long LL;
const int maxn=1e4+5;
const int maxm=1005;
const int m=1000;
void read(int& x){
char c;
bool f=0;
while((c=getchar())<48) f|=(c==45);
x=c-48;
while((c=getchar())>47) x=x*10+c-48;
x=(f ? -x : x);
return;
}
int p[maxn],a[maxn],b[maxn];
int dp[maxn][m];
int sum[maxn];
int n,q;
int main(){
read(n);
for(int i=1;i<=n;i++){
read(p[i]),read(a[i]),read(b[i]);
sum[i]=sum[i-1]+b[i];
}
for(int i=0;i<=m;i++) dp[n+1][i]=i;
for(int i=n;i>=1;i--){
for(int j=0;j<=m;j++){
if(p[i]>=j) dp[i][j]=dp[i+1][j+a[i]];
else dp[i][j]=dp[i+1][max(j-b[i],0)];
}
}
read(q);
int in;
while(q--){
read(in);
int i=lower_bound(sum,sum+n+1,in-m)-sum;
//cout<<i<<" ans=";
if(i==n+1) printf("%d\n",in-sum[n]);
else printf("%d\n",dp[i+1][in-sum[i]]);
}
return 0;
}
//^o^
E
dfs模板,给每个点的边排个序就好,不用回溯
#include<bits/stdc++.h>
#define usetime() (double)clock () / CLOCKS_PER_SEC * 1000.0
using namespace std;
typedef long long LL;
const int maxn=1005;
void read(int& x){
char c;
bool f=0;
while((c=getchar())<48) f|=(c==45);
x=c-48;
while((c=getchar())>47) x=x*10+c-48;
x=(f ? -x : x);
return;
}
int t;
vector<int> mp[maxn];
vector<int> ans;
bool vis[maxn];
int n,m,x,y;
bool dfs(int u){
if(u==y){
ans.push_back(u);
return 1;
}
for(int i=0;i<mp[u].size();i++){
int v=mp[u][i];
if(vis[v]) continue;
vis[v]=1;
if(dfs(v)){
ans.push_back(u);
return 1;
}
}
return 0;
}
int main(){
read(t);
while(t--){
read(n),read(m),read(x),read(y);
int u,v;
ans.resize(0);
for(int i=1;i<=n;i++){
mp[i].resize(0);
vis[i]=0;
}
for(int i=1;i<=m;i++){
read(u),read(v);
mp[u].push_back(v);
mp[v].push_back(u);
}
for(int i=1;i<=n;i++){
sort(mp[i].begin(),mp[i].end());
}
vis[x]=1;
dfs(x);
for(int i=ans.size()-1;i>=0;i--){
printf("%d ",ans[i]);
}
printf("\n");
}
return 0;
}
//^o^
/*
最近刚从HL中学集训回来,本来还打算写游记的,结果照片忘记拍了TT
回来ABC似乎长进不大,但能重新拾起对OI的热爱,认识到自己的不足,那就是好事吧
八月份还有一次HL集训,这次一定带回照片 ( ̄▽ ̄)
*/

浙公网安备 33010602011771号