还是菜,两题dp一题模拟
/* 反正就两个方向,往左或者往右,如果都不行,那就是-1 */ #include<bits/stdc++.h> using namespace std; int main(){ int n,x,y,d,t; scanf("%d",&t); while(t--){ scanf("%d%d%d%d",&n,&x,&y,&d); if(abs(y-x)%d==0) { printf("%d ",abs(y-x)/d); continue; } else { if((y-1)%d!=0 && (n-y)%d!=0){ puts("-1"); continue; } int r=-1,l=-1; if((n-y)%d==0){ if((n-x)%d==0) r=(n-x)/d; else r=(n-x)/d+1; r+=(n-y)/d; } if((y-1)%d==0){ if((x-1)%d==0) l=(x-1)/d; else l=(x-1)/d+1; l+=(y-1)/d; } if(l==-1) printf("%d ",r); else if(r==-1) printf("%d ",l); else printf("%d ",min(l,r)); } } }
/*
给定一串字符,只有两个字母G,S,允许交换一次任意两个字母,问交换后最长连续的G是多长
*/
#include<bits/stdc++.h> using namespace std; #define maxn 200005 int n,a[maxn]; int L[maxn],R[maxn],tot=0; int main(){ char s[maxn]; scanf("%d%s",&n,s+1); for(int i=1;i<=n;i++){ if(s[i]=='G'){ tot++; a[i]=a[i-1]+1; } else a[i]=a[i-1]; } for(int i=1;i<=n;i++) if(s[i]=='G') L[i]=L[i-1]+1; else L[i]=0; for(int i=n;i>=1;i--) if(s[i]=='G') R[i]=R[i+1]+1; else R[i]=0; int ans=0; for(int i=1;i<=n;i++){//要么是包括该点的左连续,要么是该点之前的左连续+该点之外的右连续+1 ans=max(ans,L[i]); ans=max(ans,L[i-1]+R[i+1]+1); } printf("%d ",min(ans,tot)); }
/*
一次排序后,sum[i]表示每种专业选取i个人的最大值
*/
#include<bits/stdc++.h> using namespace std; #define maxn 100005 #define ll long long ll sum[maxn]; vector<int>a[maxn]; vector<ll>::iterator it; int tot[maxn]; int cmp(int a,int b){ return a>b; }//降序排列 int main(){ int n,m,id,val,mx=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d%d",&id,&val); a[id].push_back(val); tot[id]++; } for(int i=1;i<=m;i++) sort(a[i].begin(),a[i].end(),cmp); for(int i=1;i<=m;i++){ ll tmp=0; for(int j=0;j<a[i].size();j++){ tmp+=a[i][j]; if(tmp>0)//总和为负的不能加 sum[j]+=tmp; } } ll ans=0; for(int i=0;i<n;i++) ans=max(ans,sum[i]); printf("%lld ",ans); return 0; }