[关闭]
@hhzhhzhhz 2019-06-01T16:55:01.000000Z 字数 3439 阅读 314

2017级八年级第二学期期中测试

解题报告


T1: 收件箱

题面

模拟
1. 连着的1点一次向后一格
2. 1中间的1个0也点击一次
3. 连着两个零及以上选择跳出循环,转入下一个1,过程中需要两次点击
4. 用临时变量,存储还有多少未读

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int main() {
  4. int n,a[1010],j=0;
  5. cin>>n;
  6. for(int i=1; i<=n; i++) {
  7. cin>>a[i];
  8. if(a[i]==1)j++;
  9. }
  10. a[n+1]=-1;
  11. int ans=0;
  12. for(int i=1; i<=n; i++) {
  13. if(a[i]==1) {
  14. int t=0;
  15. while((a[i] || a[i+1]) && j) {
  16. if(a[i]==1) j--;
  17. a[i]=0,t++,i++;
  18. }
  19. ans+=t;
  20. if(j) ans+=1 ;
  21. }
  22. }
  23. cout<<ans;
  24. return 0;
  25. }

T2:冰镇杨梅汁

此处输入图片的描述

  1. 预处理:
      也可写作
  2. dfs:
    预处理后,第n家店的杨梅汁的单价是最低的,所以dfs从最后一家店开始搜索。
    考虑两种情况

    1. 一次性买完 p 份
    2. 不一次性买完 p-1 份
    第n家店买的杨梅汁多余买的杨梅汁有少停止搜索比较记录ans第n-1家店继续搜索
  1. #include<bits/stdc++.h>
  2. #define LL long long
  3. LL ans=1e18,v[33],p[33],l,n;
  4. using namespace std;
  5. void dfs(int n,int l, LL m ) {
  6. if(l==0 || n==0) return ;
  7. LL tmp=((l-1)/v[n]+1)*p[n]+m;
  8. ans=min(ans,tmp);
  9. dfs(n-1,l%v[n],m+l/v[n]*p[n]);
  10. }
  11. int main() {
  12. cin>>n>>l;
  13. for(int i=1; i<=n; i++) {
  14. cin>>p[i];//价格
  15. v[i]=pow(2,i-1);//体积
  16. }
  17. for(int i=2; i<=n; i++) {
  18. p[i]=min(2*p[i-1],p[i]);
  19. }
  20. dfs(n,l,0);// 第几家店 ; 还要多少 ; 花了多少
  21. cout<<ans;
  22. return 0;
  23. }

T3:一座塔

此处输入图片的描述

搜索;
传三个参数 a: 还能放多少体积; b:已经放到多高; c:放了多少体积
每一层选择放木块或不放木块;
1. 放木块将 a-木块体积; b+1; c+木块体积
2. 不放木块 a-> 当前木块体积-1(避免下层继续选择同体积木块); b不变;c不变

  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define lowbit(x) (x)&-(x)
  4. #define N 10010
  5. #define P 10007
  6. #define D double
  7. #define ull unsigned ll
  8. using namespace std;
  9. int n;
  10. struct nod {
  11. int t,v;
  12. } ans[100010];
  13. int cnt;
  14. bool cmp(nod a, nod b) {
  15. if(a.t!=b.t) return a.t>b.t;
  16. else return a.v>b.v;
  17. }
  18. inline int read() {
  19. int x=0,f=1;
  20. char ch=getchar();
  21. while(ch<'0' || ch>'9') {
  22. if(ch=='-')f=-1;
  23. ch=getchar();
  24. }
  25. while(ch>='0'&& ch<='9') {
  26. x=x*10+ch-'0';
  27. ch=getchar();
  28. }
  29. return f*x;
  30. }
  31. void dfs(int need,int nv,int nh) {
  32. int x;
  33. for(x=1; x*x*x<=need; x++);//枚举边长
  34. if(need<=7) {
  35. ans[cnt].t=nh+need;
  36. ans[cnt].v=nv+need;
  37. cnt++;
  38. return ;
  39. }
  40. dfs(need-pow(x-1,3),nv+pow(x-1,3),nh+1);
  41. dfs(pow(x-1,3)-1,nv,nh);
  42. }
  43. int main() {
  44. n=read();
  45. dfs(n,0,0);
  46. sort(ans,ans+cnt,cmp);
  47. cout<<ans[0].t<<" "<<ans[0].v<<endl;
  48. return 0;
  49. }

T4:乘法表

此处输入图片的描述

规律+二分

  • 代码
  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define lowbit(x) (x)&-(x)
  4. #define N 10010
  5. #define P 10007
  6. #define D double
  7. #define ull unsigned ll
  8. using namespace std;
  9. inline int read() {
  10. int x=0,f=1;
  11. char ch=getchar();
  12. while(ch<'0' || ch>'9') {
  13. if(ch=='-')f=-1;
  14. ch=getchar();
  15. }
  16. while(ch>='0'&& ch<='9') {
  17. x=x*10+ch-'0';
  18. ch=getchar();
  19. }
  20. return f*x;
  21. }
  22. ll m,n,k;
  23. ll find(LL x) { // 计算比x小的数的个数df
  24. ll sum=0;
  25. for(int i=1; i<=n; i++) {
  26. sum += (m <= x/i)?m:(x/i); // min(m,x/i) 是每一行中比x小的数的个数(若i*m<=x,则会有m个数满足要求,否则会有x/i个数满足),也可以用if,else的写法 或 ? : 表达式的写法.
  27. }
  28. return sum;
  29. }
  30. ll ef(ll l, ll r, ll k) {
  31. ll mid;
  32. while(l <= r) {
  33. mid=(l+r)/2;
  34. if(find(mid) < k) l=mid+1; // 要找的数在后面,区间下限继续增大
  35. else r=mid-1; // 要找的数在前面,区间上限继续减小
  36. }
  37. return l;
  38. }
  39. int main() {
  40. cin>>m>>n>>k;
  41. cout<ef(1,n*m,k);
  42. cout<<endl;
  43. return 0;
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注