zoukankan      html  css  js  c++  java
  • Features Track[STL map]

    题目地址

    Features Track(ACM-ICPC 2018 徐州赛区网络预赛 )

    题干


    代码和解释

    题意:一个动画有许多 n 帧,每帧有 k 个点,点的坐标 (x,y) 相同则视作同一个点。先要求找出在相邻帧存在的点最多的帧数是多少。比如:点 (1,4) 在第2、3、4、7、8帧存在,则其连续存在于 2-3-4 和 7-8 帧处,其连续存在的最多帧为3帧。
    输入:T(样例组数),n(帧数),每帧输入k(此帧点数),其后跟着 2k 个整数表示 k 的点的 x 和 y 坐标。
    如果对于每一帧的每一个点存起来后依次查找其位置,则时间复杂度过高。而 STL map 使用哈希,搜索快。并且使用01滚动的方式,只需要两帧、两个map(上一个和这一个),而不需要 n 个map就可以解决此题。
    下面是本题的c++代码

    #include<bits/stdc++.h>
    using namespace std;
    //只需要看这一位和上一位即可,来回01滚动 
    map< int,map<pair<int,int>,int> > mp;//外层的key是0或1,内层的key是点的值,内层的value是连续出现几次 
    pair<int,int> p;//点p坐标x和y 
    int main()
    {
    	int T;
    	int n;
    	int k;
    	int x,y;
    	int ans;
    	int magic;//tql,magic只为0或1,异或计算 
    	scanf("%d",&T);//样例组数 
    	while(T--){
    		scanf("%d",&n);//几帧动画
    		magic = 0;//对于一个样例,初始化 
    		ans = 0;
    		while(n--){
    			scanf("%d",&k);//这一帧有几个点
    			
    			mp[magic].clear();//每帧一次,将旧的清0,当成新的 
    			
    			while(k--){
    				scanf("%d%d",&x,&y);
    				p=make_pair(x,y);//制造点
    				//1.如果magic=0,则magic^1=1。如果mp[1].count(p)不为0(则为1),说明在上一帧有p点 
    				//2.如果magic=1,则magic^1=0。如果mp[0].count(p)不为0(则为1),说明在上一帧有p点
    				//3.如果magic=0,则magic^1=1。如果mp[1].count(p)为0,说明在上一行没有p点,而在这一帧出现了p点
    				//4.如果magic=1,则magic^1=0。如果mp[0].count(p)为0,说明在上一行没有p点,而在这一帧出现了p点 
    				mp[magic][p]=mp[magic^1][p]+1;//更新p点的连续出现次数,比上次多1(上次可能是0,也可能不是0) 
    				ans=max(ans,mp[magic][p]);//更新最大连续出现次数 
    
    				//如果p点在这一帧没有出现,则对于这个p,不会走上面的这两帧。因为之前经过了每帧的 mp[magic].clear(),全部清0,所以下一次循环时,mp[magic^1][p]会为0,说明p点在这一帧没有出现。 
    			} 
    			magic^=1;//每帧一次。如果magic是1,则变为0;如果magic是0,则变为1。然后 mp[magic].clear(),清掉旧的,保留这次循环里留下的新的 
    		}
    		printf("%d
    ",ans); 
    	}
    	return 0; 
    }
    

    异或的特殊用法:偶数异或1会得到它加1,奇数异或1会得到它减1。所以使用异或1可以使0和1相互转化。

    参考

    ACM-ICPC2018徐州网络赛 Features Track(二维map+01滚动)
    记异或的妙处(异或1)

    • map:关联容器,实现从键(key)到值(value)的映射。
    • map效率高的原因:用平衡二叉搜索树来存储和访问。
      查找的复杂度是O(logn)。
    例子 说明
    map<Type1,Type2> A; 定义,key的类型是Type1,value的类型是Type2
    A[x] 返回key x到value的引用,时间复杂度为O(logn),可以用于赋值。若x不存在,则自动新建一个二元组(x,zero),并返回zero的引用
    A.size() 返回元素个数,时间复杂度O(1)
    A.empty() 判断是否为空
    A.clear() 清空A
    A.count(x) 返回A中key为x的元素个数,时间复杂度为O(logn),因为map中一个key只对应一个value,所以A.count(x)只可能为0或1
    map<Type1,Type2>::iterator it 定义迭代器it
    it->first 返回迭代器对应的key
    it->second 返回迭代器对应的value
    A.find(x) 在A中查找key为x的二元组,并返回指向该二元组的迭代器,若不存在,返回map.end(),时间复杂度为O(logn)
    A.insert(pair<Type1,Type2>(x,v)) 返回插入地址的迭代器和是否插入成功的bool并成的pair,时间复杂度为O(logn)
    A.erase(参数) 删除,参数可以是pair或者迭代器,返回下一个元素的迭代器,时间复杂度为O(logn)
  • 相关阅读:
    Windows 解压缩XX.zip.001 XX.z01分卷文件的方法
    Android Library 发布开源库 JCenter & JitPack 攻略
    常见场景下Fragment和Activity的生命周期对比
    Android Studio 插件 ADBWifi 无线调试真机
    Flutter upgrade更新版本引发的无法启动调试APP的错误 target:kernel_snapshot failed”
    Glide异常:Failed to find GeneratedAppGlideModule 解决实践
    Android 讯飞语音听写SDK快速接入(附空指针解决和修改对话框文字方法)
    Android 自定义View—清爽小巧灵活的多节点进度条
    Android EXCEL 解析 xls 和 xlsx,方法其实很简单
    解决repo从codeaurora.org同步Android代码失败问题
  • 原文地址:https://www.cnblogs.com/hardcoreYutian/p/11436951.html
Copyright © 2011-2022 走看看