Codeforces Round #378 (Div. 2) D题(data structure)解题报告

摘要:
=0)//g2不是0,即两个石头{printf;}否则{printf;}return0;}在我职业生涯中第二次遇到一对情侣时,我不禁想起了我第一次遇到他的CodeforcesRound#377E问题。这里还有一个问题解决报告#include 使用namespacestd;对c[200005];//计算机需要电源对s[200005]//插座电源longlongn,m,适配器[200005],已使用[200005]、lo[200005];ge1=0,ge2=0,i,j;intmain(){cin˃˃n˃˃m;对于{cin˃˃c[i].first;c[i].second=i;}对于{cin˃˃s[i].first;s[i].second=i;}分类分类对于{For{如果//lo不为0,这意味着找到了一个合格的套接字,让我们看看下一个图标;而//这个套接字的功率小于计算机所需的功率,让我们看下一个。由于之前已经对其进行了排序,因此在2{j++;}的每一次除法之后,顺序仍然相同//如果已使用此套接字,则只能查看下一个套接字。

题目地址

先简单的总结一下这次CF,前两道题非常的水,可是第一题又是因为自己想的不够周到而被Hack了一次(或许也应该感谢这个hack我的人,使我没有最后在赛后测试中WA)。做到C题时看到题目情况非常复杂,明显超出自己现在水平,卡了很久也没有好好做题。等了很长时间才开始看D题,而这时信心已经严重不足。赛后再看D题才发现自己比赛时理解错了题意,致使误以为题目非常复杂。而实际上,这个过程分析起来是非常容易的。

对于三种棱长度分别为a,b,c的石头,r最大为min(a,b,c)/2;。

如果两个石头要拼接,那么只能让较长的两个接在一起,否则就毫无意义。其实对于自己来说,比较困难的就是找到存储一块石头较长两条边的容器,和每一个可能可以拼的石头的编号。这里,就需要用到map整体存储,和pair存储石头的较长两边。找到这样存储的办法后,思路就是把石头一块块的扫,扫一遍后,也就得出了答案。

#include<bits/stdc++.h>
using namespace std;
int a[4];
map<pair<int ,int >,int>ma;//用名字为ma的map记录最大的两条棱长,get到map的第一位是用于排序的。
map<pair<int ,int >,int>id;//用名字为id的map记录这两条棱属于的石头的编号
int main()
{
    int i,n,g1=0,g2=0,mx=0;//g1用来记录最后选中的石头编号,g2兼起记录最后是一块石头还是两块,以及如果是两块石头那么另一块的编号是多少的作用。
    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d%d%d",&a[1],&a[2],&a[3]);
        sort(a+1,a+4);//sort排个序,方便接下来操作
        if(a[1]>mx)
        {
            mx=a[1];g1=i;g2=0;//最大值的产生有两种情况,这是其一,某块石头的最小棱长大于原本的最大值。如果产生了新的最大值,那么此时为一块石头的情况,将g2赋为0.
        }
        if(min(ma[make_pair(a[2],a[3])]+a[1],a[2])>mx){//注意拼接完的时候最小棱可能是新生成的棱,也可能是原本第二长的棱。
            mx=min(ma[make_pair(a[2],a[3])]+a[1],a[2]);
            g1=id[make_pair(a[2],a[3])];g2=i;//这是最大值产生的第二种情况。将g1、g2分别记录两块石头的编号。
        }
        if(a[1]>ma[make_pair(a[2],a[3])])//if里的内容实际上含义为,如果这块石头现在无法以较长的两棱拼接。这时,就要先将最短的棱的值赋给这个map,方便接下来使用。
        {
            ma[make_pair(a[2],a[3])]=a[1];
            id[make_pair(a[2],a[3])]=i;
        }
    }
    if(g2!=0)//g2不为0,也就是两块石头的情况
    {
        printf("2
%d %d
",g1,g2);
    }
    else
    {
        printf("1
%d
",g1);
    }
    return 0;

}

做题生涯第二次遇到pair,不由得想到了第一次遇见pair的Codeforces Round #377 (Div. 2) E题,这里也写一下解题报告。

题目地址

解题思路:

关键还是要找到恰当的容器存储电脑需要的电、插座的电,以及电脑插到的插座的位置,第几个电源按的分压器数量。头一次见到pair,真的是耳目一新。自己还是太弱,直到的太少,继续加油吧。

#include<bits/stdc++.h>
using namespace std;
pair <long long ,long long >c[200005];//电脑需要功率
pair <long long ,long long >s[200005];//sockect 插座功率
long long n,m,adapter[200005],used[200005],lo[200005],ge1=0,ge2=0,i,j;
int main()
{
    cin>>n>>m;
    for(i=1;i<=n;i++)
    {
        cin>>c[i].first;
        c[i].second=i;
    }
    for(i=1;i<=m;i++)
    {
        cin>>s[i].first;
        s[i].second=i;
    }
    sort(c+1,c+1+n);
    sort(s+1,s+1+m);
    for(int z=0;z<33;z++)
    {
        for(i=1,j=1;i<=n;i++)
        {
            if(lo[c[i].second])//lo非0,意为已经找到了符合条件的插座,那么就看下一个i
                continue;
            while(j<=m&&(s[j].first<c[i].first))//这个插座功率小于电脑需要功率,那么就看下一个,由于之前排过序,之后每次统一除2,顺序仍不变
            {
                j++;
            }
            while(j<=m&&used[s[j].second])//如果这个插座用过了,那么也只能看下一个。
            {
                j++;
            }
            if(j<=m&&!used[s[j].second]&&s[j].first==c[i].first)//if里给出可以插上的所有条件,插座满足范围,没用过,且电流相等
            {
                lo[c[i].second]=s[j].second;//这时,这个电脑的插座位置就是这个插座的序号
                used[s[j].second]=1;//将该插座标记为用过
                adapter[s[j].second]=z;//这个插座的分压器数量为此时除z进行到的轮数
                ge1++;//可以插电的电脑+1
                ge2+=z;//要使用的分压器数加上此时的轮数
            }
        }
        for(i=1;i<=m;i++)
        {
            s[i].first=(s[i].first+1)/2;//进行插座统一减半操作
        }
    }
    cout<<ge1<<" "<<ge2<<endl;
    for(i=1;i<=m;i++)
    {
        cout<<adapter[i]<<" ";//全都要输出,未使用的默认为0
    }
    cout<<endl;
    for(i=1;i<=n;i++)
    {
        cout<<lo[i]<<" ";
    }
    cout<<endl;
}

总结:前路漫漫,要学的还有太多,知识上还是欠缺太多。不过学习阶段,rating不断的掉又有何妨,只要坚持下去,终有一天rating会得到提高。

补题过程中看到那么多从未见过的东西,艰难自学的过程是痛苦的,可是学会后也可以应用的感觉又是无比的令人感到充实与快乐。

勿忘初心,勇往直前!

免责声明:文章转载自《Codeforces Round #378 (Div. 2) D题(data structure)解题报告》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇[Google Guava] 8-区间SQL优化(Oracle)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

PLSQL常用配置之窗口/版面保存、SQL格式化/美化、SQL注释去掉注释等快捷键配置、登陆历史修改配置

//Blog.csdn.net/eyeidolon/article/details/8251791 PLSQL常用配置的快捷键配置,如窗口/布局保存、SQL格式化/美化和SQL注释删除,以及登录历史修改1的配置。PL/SQLDeveloper记住登录密码当使用PL/SQLDeveloper时,默认情况下PL/SQLDeveloper会执行此窗口中的所有SQL...

Activiti-个人任务

1.分配任务所有者1.1固定分配在业务流程建模期间指定固定任务所有者;在properties视图中,填写Assignee项作为任务所有者;注:通过固定分配方法,任务是逐步执行的,任务负责人将根据bpmn的配置分配给每个任务;1.2表达式分配1.2.1 UEL表达式Activiti使用UEL表达式,UEL是javaEE6...

DB2锁表或超时解决方案

命令如下:db2"forceapplication"4、使用命令listapplication查看是否已经断开了哪些进行了死锁的进程。...

GitLab的基础使用-创建用户(users)

否则,将追究法律责任。1、 以管理员身份登录GitLab的WebUI,并创建用户1˃使用管理员登录GitLab。管理员登录成功后,点击下图所示的小扳手,然后点击进入管理员的Dashboard界面。如果时间间隔过长,可以要求运维人员重置密码。操作和维护人员可以参考第一步来重置用户的密码。实际上,您也可以通过参考第三步中的方法找到自己的密码,而不必麻烦操作和维护...

Makefile 使用总结

1.Makefile简介Makefile是和make命令一起配合使用的.很多大型项目的编译都是通过Makefile来组织的,如果没有Makefile,那很多项目中各种库和代码之间的依赖关系不知会多复杂.Makefile的组织流程的能力如此之强,不仅可以用来编译项目,还可以用来组织我们平时的一些日常操作.这个需要大家发挥自己的想象力.本篇博客是基于{精华}跟我...

myEclipse

因此,更改windows–>preferences–>general–>editors–>fileassociations,将myeclipsejspedator设置为默认的myeclipse使用提示步骤5:更改代码提示快捷键。当前代码提示快捷键默认为ctrl+space,我们的输入方法也被切换,因此会出现冲突。...