返回顶部
  • 管理
  • 【20200318 FZOJ C2022第一次网络测试赛 普及组-难度】

    FZOJC2022第一次网络测试赛

    以下所有题都不挂题面,自行到FZOJ查看...

    A.渔夫
    Time:1s   Memory:128M

    【题目大意】:输出第一段话的字数

    【思路分析】:打卡题,输出2即可。

    【参考代码】

    #include <bits/stdc++.h>
    using namespace std;
    int main(){
        cout<<2<<endl;
        return 0;
    }
    
    B.物资支援清单
    Time:1s   Memory:128M

    【题目大意】:题目应该已经说得很明白了

    【思路分析】:排序题,按照题目所讲的条件进行排序。但由于\(n \leq 100000\),简单排序算法\(O(N^2)\)肯定不能过。所以你得采用快排等\(O(NlogN)\)的算法,或者简单易写的sort,然后再cmp函数里面写好排序的条件即可。

    最后,注意一下变量的数据类型。

    【参考代码】

    #include<bits/stdc++.h>
    using namespace std;
    const int  N = 100000+5;
    int n;
    struct Things
    {
    	double id,price,num,total;  //id编号,price单价,num数量,total总价
    }a[N];
    bool cmp(node x,node y)
    {
    	if(x.total==y.total){  //如果总价相同
    		if(x.price==y.price)  //如果单价也相同
    			return x.id>y.id;  //那就比较编号
    		return x.price>y.price;  //否则比较单价
    	}
    	return x.total>y.total  //比较总价
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1; i<=n; i++)
    	{
    		scanf("%lf%lf",&a[i].price,&a[i].um);
    		a[i].id=i;
    		a[i].total=a[i].price*a[i].num;
    	}
    	sort(a+1,a+1+n,cmp); //sort排序
    	for(int i=1; i<=n; i++)
    		printf("%.0lf %.0lf %.3lf\n",a[i].id,a[i].num,a[i].total);
    }
    
    C.考室分配
    Time:1s   Memory:128M

    【题目大意】:有n间考室在坐标为\(a_1 \cdots a_n\)上,需要分配m个人到这些考室中(m<n),求一个间隔距离d,使得间隔的最短距离最大。

    【思路分析】:二分答案裸题,求什么最小的最大,什么最大的最小。一旦题目这样问,一般都是标准的二分答案的题目,当然这道题也是。

    我们二分距离mid,用check函数去判断这个mid是否能让m个人都分配到考室中。如何判断能分配呢?如果两个考室之间的距离大于mid,那么就可以把学生放进去,人数sum++。最后遍历完,发现\(sum \geq m\),那说明这个距离mid是可行的。

    但由于要求最大,所以我们还可以继续把mid放大,反复check,直到sum<m时,答案就是上一个mid。

    【参考代码】

    #include<bits/stdc++.h>
    using namespace std;
    const int  N=  200000+5;
    int n,m;
    long long a[N],ans;
    int check(long long x)
    {
        int pos=1,sum=1;  //sum表示可以分配的学生人数
        for(int i=2; i<=n; i++)
            if(a[i]-a[pos]>=x) pos=i,sum++;  //如果距离大于,说明可以把学生放到这个考场,sum++
        return sum>=m;  //返回判断结果,看距离为x时是否能放下m个人
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++)
            scanf("%lld",&a[i]);
        sort(a+1,a+1+n);  //二分答案前先排序
        long long l=1,r=200000;
        while(l<=r)
        {
            long long mid=(l+r)>>1;
            if(check(mid)) ans=mid,l=mid+1;  //如果mid能分配完m个人,那就尝试更大的mid,放大距离
            else r=mid-1;
        }
        printf("%lld",ans);
        return 0;
    }
    
    
    D.考室准备
    Time:1s   Memory:128M

    【题目大意】:给出三个数组a,b,p,a数组是底数,b数组是幂,p数组是模数,进行对位取余运算

    【思路分析】:本题就是【FZOJ1421 取余运算】的数组版,如果这道题都还没做的同学建议去补一下坑。会做取余运算之后,相信不难看懂下面的代码。

    【参考代码】

    #include<bits/stdc++.h>
    using namespace std;
    const int  N = 100+5;
    int n,a[N][N],b[N][N];
    long long f(int n,int m,int p)  //快速取余
    {
    	if(m==0) return 1;
    	if(m%2==1)	return (long long)(n*f(n,m-1,p)%p);
    	long long num=f(n,m/2,p)%p;
    	return num*num%p;
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1; i<=n; i++)
    		for(int j=1; j<=n; j++)
    			scanf("%d",&a[i][j]);
    	for(int i=1; i<=n; i++)
    		for(int j=1; j<=n; j++)
    			scanf("%d",&b[i][j]);
    	for(int i=1; i<=n; i++){
    		for(int j=1; j<=n; j++){
    			int p;
    			scanf("%d",&p);
    			printf("%lld ",f(a[i][j],b[i][j],p));  //取余,输出结果
    		}
    		printf("\n");
    	}
    	return 0;
    }
    
    E.自动售票机
    Time:1s   Memory:128M

    【题目大意】:给出一系列的目的地名字(其实就是字符串),问当按下某个字符,会自动过滤一些字符并提示能够按下的字符。问当按下某种情况之后,键盘的显示情况。

    【思路分析】:模拟题,主要考查对字符串操作的使用和理解。做法有很多,思路不同,代码的写法也不同,只要保证能正确的模拟题目的操作即可。

    本题主要的就是对字符串的比较,然后正确的显示键盘的情况,这里的键盘建议最好打一成一张表,通过标记flag来让哪些显示为本来的字符,哪些显示为“*”。

    【参考代码】

    代码难得挂了,洛谷社区有很多别人的各种写法, 找到一种自己能理解的来看吧。

    洛谷题解

    posted @ 2020-03-18 21:35  QYcccccccc  阅读(121)  评论(0)    收藏  举报