C 周赛题

目录

A

B

C

D

E

F


A

 

题目大意:
给定杆子长度和蚂蚁数量,蚂蚁分别在杆子的不同位置,每只蚂蚁随机选杆子的一个方向走,当蚂蚁相遇的时候就往相反的方向走,求杆子蚂蚁全部走出杆子的最少时间和最长时间
题目分析:
当两只蚂蚁相遇就反向走,我们可以把这当作擦肩而过,也就是当这个条件没有.为什么可以当作没有这个条件呢?...因为当两只蚂蚁相遇的时候,表面来看这两只蚂蚁要立马掉头,但是我们也可以当做这两只蚂蚁互相交换了,也就是擦肩而过了..
然后我们就只考虑蚂蚁往 2 个方向花的时间
求最小值的话也就是找到最大的往一边较小的时间
求最大值的话也就是找到最大的往一边较大的时间
(我就是把问题想的太复杂了555好好的签到题楞是没有做出来....唉)
#include <iostream>
using namespace std;
int n,len,x;
int a;

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&len,&x);
        int minn=0,maxn=0;
        for(int j=1;j<=x;j++){
            scanf("%d",&a);
            minn = max(min(len-a,a), y );
            maxn = max(max(len-a,a), z );
            
        }
        printf("%d %d\n",minn,maxn);
        
    }
    return 0;
}

int minn=0,maxn=0;  每次循环一定不要忘记初始化啊!!555..我是fw..

B

题意翻译

题目描述

数组 a 有 n 个元素,需要进行 q 次操作。

操作1:将第 i 号元素改为 x

操作2:将数组中所有元素改为 x

每次操作完成后,输出当前数组中所有元素的总和。

输入格式

第一行两个整数 n,q (1≤n,q≤2×1e5)

第二行 n 个整数,表示 a 中的元素 (1≤ai​≤1e9)

接下来有 q 行,首先输入一个整数 t(t∈1,2)

若 t=1,接着输入两个整数 i,x(1≤i≤n,1≤x≤1e9)

若 t=2,接着输入一个整数 x(1≤x≤1e9)

输出格式

共 q 行,每行一个整数,表示当前数组 a 中所有元素的和

输入样例:

5 5
1 2 3 4 5
1 1 5
2 10
1 5 11
1 4 1
2 1

输出样例:

19
50
51
42
5

这题我一开始就理解错题目的意思了,导致认为自己写的贼对 还怀疑样例错了。错在没有看注释,这题每次进行了一次操作之后,这n个整数也会进行相应的改变而影响下一次操作,所以说每次操作并不是独立进行的。这也是这个题的难点所在qwq...

然而重新写一遍还是错的...

 我的错误暴力代码:

#include <iostream>
using namespace std;
int main(){
    int n,k,x,a,b,c;
    int sum[200010],s[200010];
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%d",&s[i]);
        sum[i]=sum[i-1]+s[i];
    }
    for(int i=1;i<=k;i++){
        scanf("%d",&x);

        if(x==2){
            scanf("%d",&c);
            printf("%d\n",c*n);
			for(int i=1;i<=n;i++){
                s[i]=c;
                sum[i]=sum[i-1]+s[i];
            }
        }
        if(x==1){
            scanf("%d%d",&a,&b);
            printf("%d\n",sum[n]+b-s[a]);
            sum[n]=sum[n]+b-s[a];
            s[a]=b;
        }
    }

   
    return 0;
}

错误1:没有开long long ,元素ai的范围在1~1e9,求和的话会爆int.

错误2:方法不对,这样做还是超时了,时间复杂度为O(n*k),n,k的范围在1~2e5,相乘就是4*1e10而计算机1秒的运算速度大概在10的8次方,最坏情况下要运行几百秒

还有一点,定义数组和变量最好写在main的上面,系统初始自动赋零

C

 Description

It is very hard to wash and especially to dry clothes in winter. But Jane is a very smart girl. She is not afraid of this boring process. Jane has decided to use a radiator to make drying faster. But the radiator is small, so it can hold only one thing at a time.

Jane wants to perform drying in the minimal possible time. She asked you to write a program that will calculate the minimal time for a given set of clothes.

There are n clothes Jane has just washed. Each of them took ai water during washing. Every minute the amount of water contained in each thing decreases by one (of course, only if the thing is not completely dry yet). When amount of water contained becomes zero the cloth becomes dry and is ready to be packed.

Every minute Jane can select one thing to dry on the radiator. The radiator is very hot, so the amount of water in this thing decreases by k this minute (but not less than zero — if the thing contains less than k water, the resulting amount of water will be zero).

The task is to minimize the total time of drying by means of using the radiator effectively. The drying process ends when all the clothes are dry.

Input

The first line contains a single integer n (1 ≤ n ≤ 100 000). The second line contains ai separated by spaces (1 ≤ ai ≤ 109). The third line contains k (1 ≤ k ≤ 109).

Output

Output a single integer — the minimal possible number of minutes required to dry all clothes.

描述

在冬天洗衣服和晾衣服是一件很难的事情。但Jane是一个非常聪明的女孩。她不怕这个无聊的过程。Jane 决定使用散热器来加快干燥速度。但是散热器很小,一次只能容纳一件东西。

Jane 希望在尽可能短的时间内进行干燥。她要求你写一个程序来计算给定一套衣服的最短时间。

Jane刚洗过的衣服有n个。每件衣服在洗涤时都吸收了ai滴水量。每分钟每件衣服中所含的水量就会减少 1(当然,在衣服还没有完全干燥的情况下)。当所含水量变为零时,布料变干并准备包装。

每分钟,Jane都可以选择一件东西在散热器上晾干。散热器非常热,所以这个东西的水量在这一分钟减少了k(但不小于零——如果这个东西含有少于k的水,则得到的水量将为零)。

任务是通过有效使用散热器来最大限度地减少干燥的总时间。当所有衣服都干燥时,干燥过程结束。

输入

第一行包含单个整数 n (1 ≤ n ≤ 100 000)。第二行包含用空格分隔的 i (1 ≤ ai ≤ 1e9)。第三行包含 k (1 ≤ k ≤ 1e9)。

输出

输出单个整数,即烘干所有衣服所需的最小可能分钟数。

样例输入:

sample input #1
3
2 3 9
5

sample input #2
3
2 3 6
5

样例输出:

sample output #1
3

sample output #2
2

思路:

题目大意是n件衣服,自然烘干1分钟1滴水量,烘干机1分钟 k-1 滴水量 (注意看题目描述!:The radiator is very hot, so the amount of water in this thing decreases by k this minute (but not less than zero — if the thing contains less than k water, the resulting amount of water will be zero).   这件衣服在这一分钟减少了k滴水量,但是这其中有1滴水量是自然烘干的,k其实是两种风干速度相加)

真的很难想象这是一个二分题。二分的是时间,最好的情况是自然烘干和烘干机同时结束。因为自然烘干1分钟1滴水量,所以我们二分的时间t也就相当于自然烘干的水量。设自然烘干时间为mid,然后判断烘干机的时间为多少,设为sum,如果sum<=mid,说明烘干机的时间少了,则左区间搜索mid

AC代码:

#include <iostream>
#include <cmath>
using namespace std;
int n,k;
int a[100010];
//mid代表自然烘干时间 
int check(int mid){
	long long sum=0;
	for(int i=1;i<=n;i++){
		if(a[i]>mid) sum+=ceil((double)(a[i]-mid)/(k-1)*1.0);
	} 
	if(sum<=mid) return 1;
	else return 0;
}
int main(){
	while(scanf("%d",&n)!=EOF){
		int maxa=0;
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			maxa=max(a[i],maxa);
		}
		scanf("%d",&k);
		if(k==1){
			printf("%d\n",maxa);
			break;
		}
		
		int l=0,r=maxa;
		while(l<r){
			int mid=(l+r)/2;
			if(check(mid)) r=mid;
			else l=mid+1;
		}
		printf("%d\n",l);
		
	}
	return 0;
}
  1. while(scanf("%d",&n)!=EOF)    注意输入
  2. long long sum=0; 一定要记得开long long !
  3. int maxa=0;  每次的测试数据都要再次初始化maxa!
  4. if(k==1)   k==1的时候要特判!
  5. sum+=ceil((double)(a[i]-mid)/(k-1)*1.0);  这就是本题最难的地方了,首先要理解烘干机的速度是1分钟k-1滴水量,然后数据还要上取整ceil,最后a[i]不要忘记减去mid自然烘干的水量

总结一下就是坑太多了,而且很难想到用二分,我只会暴力555  疯狂TLE...

D

E

F

 

样例输入:

4 11
8.02
7.43
4.57
5.39

样例输出:

2.00

题目大意:

N 条绳子,他们的长度分别是 Li 。如果从他们中切割出 K 条长度相同的绳子的话,这 K 条绳子每条最长能有多长?答案保留2 位小数。
题目分析:
浮点数二分
二分的是绳子的长度,设mid为最长的长度
二分的条件是符合长度的绳子的数量,要满足mid的数量,cnt算出符合的数量,如果cnt>=mid,说明绳子还能更长,右区间搜索.
AC代码:
#include <iostream>
#include <cmath>
using namespace std;
int n,k,cnt=0;
double a[10010];
double len=0,sum=0;

int check(double mid){
    cnt=0;
    for(int i=1;i<=n;i++){
        cnt+=a[i]/mid;
    }
    
    if(cnt>=k) return 1;
    return 0;
}
int main(){
    
    scanf("%d%d",&n,&k);
	
    for(int i=1;i<=n;i++){
        scanf("%lf",&a[i]);
        sum+=a[i];
        len=max(a[i],len);
    }
    
    double l=0,r=len;
    while(r-l>1e-6){
        double mid=(l+r)/2;
        
        if(check(mid))  l=mid;
        else  r=mid;
    }
    
    printf("%.2lf", int(r*100)*0.01);

    return 0;
}

这题我有两点错误:都是在最后输出的地方(

  1.  int(r*100)*0.01  这里不能写 l,可能是因为这题是求最大,所以最好往右取,(虽然我测了很多样例写l都是对的)
  2.  int(r*100)*0.01  还要下取整,这题不能四舍五入. 下取整还可写成 floor(r*100)*0.01. 不能像我一样写  r-0.005 虽然我感觉这样写然后再四舍五入跟下取整的效果是一样的,比如2.4499999 - 0.005 后四舍五入保留两位小数为 2.44,2.440000 - 0.005 后四舍五入为 2.44.不懂为啥WA)

然后这题还有些小细节可以更好

  1.  while(r-l>1e-6) 最好加上 while( fabs (r-l>1e-6)) 求绝对值的意思
  2. scanf("%d%d",&n,&k) 改成while(scanf("%d%d",&n,&k)!=EOF)
  3. 二分的右端点可以改为能切得绳子的最优情况,即sum/k

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值