Link:
一套非常简单的题目,但很多细节都是错了一次才能发现啊……
还是不能养成OJ依赖症,交之前先多想想corner case!!!
A:
模拟,要特判0啊
#include <bits/stdc++.h> using namespace std; #define X first #define Y second typedef long long ll; typedef double db; typedef pair<int,int> P; int n; void solve(int x) { if(x<5) printf("O-|"); else printf("-O|"); if(x>=5) x-=5; for(int i=1;i<=x;i++) printf("O"); printf("-"); for(int i=1;i<=4-x;i++) printf("O"); puts(""); } int main() { scanf("%d",&n); if(!n) solve(0);//特判0! while(n) solve(n%10),n/=10; return 0; }
B:
模拟,范围是$1.5*1e5$!!!仔细读题啊
#include <bits/stdc++.h> using namespace std; #define X first #define Y second typedef long long ll; typedef double db; typedef pair<int,int> P; int n,k,cur,dat[150005];P res; //范围是1.5*1e5! int main() { scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%d",&dat[i]); for(int i=1;i<=k;i++) cur+=dat[i]; res.X=1;res.Y=cur; for(int i=1;i<=n-k;i++) { cur-=dat[i];cur+=dat[i+k]; if(res.Y>cur) res.Y=cur,res.X=i+1; } printf("%d",res.X); return 0; }
C:
string.erase和vector.erase一样,尽量不要用
期望复杂度是$O(n)$级别的
此题为了支持删除我还手写了个链表……
其实不用两次扫描+删除+输出,只要扫一遍,边扫边判断当前字母能否加入答案就行了
#include <bits/stdc++.h> using namespace std; #define X first #define Y second typedef long long ll; typedef double db; typedef pair<int,int> P; const int MAXN=2e5+10; char s[MAXN];int len,k,nxt[MAXN]; int main() { scanf("%s",s+1);len=strlen(s+1); for(int i=1;i<=len;i++) nxt[i]=i+1; k=1;nxt[len+1]=len+1; while(nxt[nxt[k]]!=len+1) if(s[k]==s[nxt[k]]&&s[nxt[k]]==s[nxt[nxt[k]]]) nxt[k]=nxt[nxt[k]]; else k=nxt[k]; k=1; while(nxt[nxt[nxt[k]]]!=len+1) if(s[k]==s[nxt[k]]&&s[nxt[nxt[k]]]==s[nxt[nxt[nxt[k]]]]) nxt[nxt[k]]=nxt[nxt[nxt[k]]]; else k=nxt[k]; k=1; while(k!=len+1) printf("%c",s[k]),k=nxt[k]; return 0; }
D:
答案的可行性具有单调性,明显可以二分
由于使用自己的钱数为$a-sum p_i$,和哪些人参与购买无关
因此每次判断时可以采取贪心的策略
1、选择拥有钱数最多的$k$个人和价格最低的$k$个车购买
2、为了使额外挪用的钱数不超过$a$,人和车从小到大排序后一一对应明显是最优的选择
最后要特判$sum p_ile a$的情况,此时直接减会出现负数,因此要用最终答案和0取max!!!
#include <bits/stdc++.h> using namespace std; #define X first #define Y second typedef long long ll; typedef double db; typedef pair<int,int> P; const int MAXN=1e5+10; int n,m,a,p[MAXN],b[MAXN];ll pre[MAXN]; bool check(int x) { ll sum=0; for(int i=1;i<=x;i++) if(b[n-x+i]<p[i]) sum+=p[i]-b[n-x+i]; return sum<=a; } int main() { scanf("%d%d%d",&n,&m,&a); for(int i=1;i<=n;i++) scanf("%d",&b[i]); for(int i=1;i<=m;i++) scanf("%d",&p[i]); sort(b+1,b+n+1);sort(p+1,p+m+1); for(int i=1;i<=m;i++) pre[i]=pre[i-1]+p[i]; int l=0,r=min(m,n); while(l<=r) { int mid=(l+r)>>1; if(check(mid)) l=mid+1; else r=mid-1; }//答案一定要记得取MAX! printf("%d %d",r,max(pre[r]-a,0ll)); return 0; }
E:
貌似题解出锅了……
后面再填吧,其实就是一个预处理+暴力枚举