zoukankan      html  css  js  c++  java
  • CF edu #85

    CF edu #85

    A.模拟

    一个游戏

    给定n对数按时间发展顺序给出,每对第一个表示当前尝试次数,第二个表示当前过关次数

    问当前数据错没错

    思路:显然数据没错的话,尝试次数,过关次数不能下降,以及下次尝试次数-上次>=下次通关次数-上次的

    B.数学

    给定一个队人,每人有不同质量的东西,你有一个操作:取序列中任意多的人出来,把质量全加起来,计算平均数还给这些人

    给定x,现问你通过若干次操作,最多能让多少人的质量大于x

    思路:从大到小排序,统计前缀和/当前数量,只要>=x,就往后移

    C.数学

    给定一个环,上面有很多BOOMer,i位置的BOOMer血量a[i],死了炸i+1位置b[i]的血(i+1死了就无伤),问你要至少造成的伤害是多少,使得BOOMer死完

    思路:如果说我们找到了最先炸的BOOMer,由于贪心性,肯定是以它开始,按顺时针遍历炸最优

    至于从谁开始炸我们先放一边,我们先单纯看看如果前者炸了后者还有多少血,预处理一波,接下来还有多少血(存前者里,记为数组c),显然,这些伤害是一定要打满的

    接下来,我们要找一个开始的位置,开始的位置,显然引爆它花费a,但是,因为它是你手动引爆了,所以它上一个位置所需要额外打出的火力就不需要了,换言之,我们现在就要找

    最小的a[i]-c[i-1](开始位置为i)

    注意快读,不然好像会t

    AC:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    using namespace std;
    #define INF 1e10+5
    #define maxn 333005
    #define minn -105
    #define ll long long int
    #define ull unsigned long long int
    #define uint unsigned int
    #define re register
    inline ll read()
    {
        re ll t=0;
        re char v=getchar();
        while(v<'0')v=getchar();
    	while(v>='0')
    	{
            t=(t<<3)+(t<<1)+v-48;
        	v=getchar();
    	}
    	return t;
    }
    ll max(ll a,ll b)
    {
        return a>b?a:b;
    }
    ll min(ll a,ll b)
    {
        return a>b?b:a;
    }
    ll a[maxn],b[maxn],c[maxn];
    void solve()
    {
        int n;
        n=read();
        ll ans=0;
        for(int i=0;i<n;i++)
        {
            a[i]=read(),b[i]=read();
        if(i)c[i-1]=max(0,a[i]-b[i-1]),ans+=c[i-1];
        }
        c[n-1]=max(0,a[0]-b[n-1]),ans+=c[n-1];
        ll curmin=a[0]-c[n-1];
        for(int i=0;i<n;i++)
        {
            curmin=min(curmin,a[i]-c[i-1]);
        }
        cout<<ans+curmin<<endl;
    }
    int main()
    {	
    	ll t;
    	t=read();
    	for(ll i=0;i<t;i++)
    	{
    	    solve();
    	}
    	return 0;
    }
    

    D.数学,模拟,贪心

    题意是给定n,l,r

    n个点,点点间有两条相反的有向边

    求一条欧拉回路,使得遍历节点的字典序最小,输入第l个到第r个

    思路:

    首先,根据贪心原则,出发点肯定是1

    其次它形成的是欧拉回路,而根据欧拉回路的要求,所有边要且仅能访问一次,显然你点1的入边肯定有n-1条,也就是说它点遍历序列中1肯定还要出现n-1次,那么这n-1次越前,肯定字典序越小。

    而n-1次中,对于剩下n-1个标号有序的点而言,刚好每点访问一次,那么就刚好就是有序排列地访问

    即121314151617...1n——共2n-2个

    接下来根据贪心原则,我们访问点2,原理与上相同,只不过1已经访问过了,故对于2形成的子序列是

    23242526...2n——共2n-4个

    显然我们可以推得全序列

    最后一位一定要记得它会返回1,加个特判即可

    AC:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    #define INF 1e10+5
    #define maxn 105
    #define minn -105
    #define ll long long  int
    #define ull unsigned long long int
    #define uint unsigned int
    #define re register
    	inline ll read()
    {
        re ll t=0;
        re char v=getchar();
        while(v<'0')v=getchar();
        while(v>='0')
        {
            t=(t<<3)+(t<<1)+v-48;
            v=getchar();
        }
        return t;
    }
    void solve()
    {
        ll n,a,b,p=1;
        bool ok=0;
        n=read(),a=read(),b=read();
        if(b==n*(n-1)+1)b--,ok=1;
        for(;p<=n-1;p++)
            if(p*(n*2-p-1)>=a)break;
        ll sum=a-(p-1)*(n*2-p)-1,num=p+sum/2;
        for(ll cur=a;cur<=b;cur++)
        {
            sum++;
            if(sum>2*(n-p))
            {
                p++;
                sum=1,num=p;
            }
            if(cur&1)cout<<p<<" ";
            else cout<<++num<<" ";
        }
        if(ok)cout<<1<<endl;
        else cout<<endl;
    }
    int main()
    {
        int t;
        cin>>t;
        for(int i=0;i<t;i++)
        {
            solve();
        }
        return 0;
    }
  • 相关阅读:
    2017.3.17作业
    2017.3.16作业
    2017.3.15作业
    2017.3.14作业
    2017.3.13作业
    2017.3.10作业
    网站流量日志分析(数据 采集之 Flume 采集)
    网站流量日志分析(模块开发——数据仓库设计)
    日常问题及解决
    可爱的生活
  • 原文地址:https://www.cnblogs.com/et3-tsy/p/12683732.html
Copyright © 2011-2022 走看看