zoukankan      html  css  js  c++  java
  • UVA

    /*
    
       A.该题思路:
       如果四重循环枚举 r1, r2, c1, c2,那么枚举时间过大,肯定会TLE
       
       解决方法:
       只枚举 c1, c2, 然后从上到下扫描各行。每次碰到一个新的行r,把c1 和 c2两列的内容作为一个二维数组存入map,如果map的键值已经存在这个二元组,二元映射到的就是所要求的r1,而当前行就是r2
       
       细节优化:
       如何表示由c1 和 c2 构成的二元组?
       a.直接用两个字符串拼接成一个长字符串(中间用一个不可能出现的字符分隔),但是速度比较慢(因为map再查找元素时,要进行字符串的比较操作)
       
       b.(更值得推荐)
       在主循环之前先做一个预处理--给所有字符串分配一个编号,则整个数据库中每个单元格都变成了整数,上述二元组就变成了两个整数
       
    
      B. 一些说明
      1.
      这题和 UVA - 12096 The SetStack Computer 又异曲同工之妙,链接见下:
      http://blog.csdn.net/mofushaohua_ln/article/details/77714856
      
      两题的相似之处在于,都采用了为元素编写一个ID,用 ID去对应真正的元素的思想
      
      而两者也有不同的地方,主要在于:
       UVA - 12096 之所以将 Set 标号,是因为题目是要构造集合的集合并压栈,很难真正去用程序来表示出集合的集合,所以分配ID,把集合等效为其ID,在必要时在通过ID去找到对应的集合,势在必行
       
       而这道题,其实是可以拼接字符串存入map,但关键是string类太慢,string的比较所需的时间可能让人无法接受
       
       所以,一个是因为“不得不为”, 一个是因为“这样更好”,其实是有区别的
       
       2.注意相等的两行两列,列并不一定要相邻,在枚举c1,c2的时候,务必两重循环
       
       3.注意判断两列是否有相等元素时,是通过 map<node,int>findrow 是否存在判断的,所以每次重新枚举两列的组合,都要重新清空findrow
       
       4. 注意在输入新一轮数据之前,有关的 map 和 vector都要先清空,其中IDmap需要逐行清空
       
       5. 
       
       如果要用map对自定义类型进行查找,一定不要忘记了重载 < ,相关解释可见:
       http://bbs.csdn.net/topics/190076742
       
       注意重载小于号时,要设置为class类的常函数
       至于为什么要这样,目前
       我也没有太明白,但是如果函数外不加const, 会编译错
       
       有关常函数的知识复习可参见这个blog:
       http://blog.csdn.net/whyglinux/article/details/602329
       
       6.对于输入的问题,其实该博主的这个方法确实略有些麻烦
       刘汝佳前辈的代码(他的代码可见本博文法二)中,是用读取整行stinrg,再用stringstream来找逗号的思路,但是《入门经典》P105曾有言:
       虽然string和stringstream很方便,但string很慢,sstream更慢,应谨慎使用
       
       所以,其实博主应该是出于对于时限的考虑,虽然这题没卡那么严,但是知道卡得严时,应该怎么处理,也是十分必要的
       
       
       声明:
       代码参考了:
       http://blog.csdn.net/wowowoc/article/details/40554525
       
    */



    #include <iostream>
    #include <cstdio>
    #include <map>
    #include <vector>
    #include <string>
    using namespace std; 
    const int ROW = 1e4 + 10;
    const int COL = 15; 
    int n, m;
    
    map<string, int> IDcache;
    vector<string> Scache; //set cache
    vector<int> IDmap[ROW]; //IDmap[i][j]表示位置(i+1, j+1)对应的字符串的ID
    
    struct node
    {
    	int x, y;
    	node(int _x, int _y):x(_x), y(_y){ }
    	bool operator < (const node& a) const
    	{
    		return (x < a.x) || (x == a.x && y < a.y); //如果要将自定义的结构体作为map的键值,则必须重载 < 号, 
    	}
    };
    map<node, int> findrow; //node对应的是该行在r1, r2列的两个字符串的ID组成的集合,如果这两个字符串已经出现过了,说明找到了,若没有,则将该行对应下标存作 findrow,作为 node(key)对应的的值(value)
    
    //找到字符串s的对应ID,如果找不到,就分配一个ID 
    int ID (string s)
    {
    	if (IDcache.count(s)) return IDcache[s];
    	Scache.push_back(s);
    	return IDcache[s] = Scache.size() - 1;
    }
    
    void input()
    {
    	string s;
    	char ch = getchar();
    	for (int i = 0; i < n; i++)
    	{
    		while (1)
    		{
    			ch = getchar(); //接受输入完n、m之后得到的回车
    			if (ch == '
    ' || ch == '
    ') // 说明该行(m个字符串的)读取结束,为当前串分配ID,ID压入IDmap[i]
    			{
    				IDmap[i].push_back(ID(s));
    				s.clear();
    				break;
    			}
    			else if (ch != ',') //说明只是读入正常的字符,将它们放入当前串中
    			{
    				s += ch;
    			}
    			else //,说明该行又读完了一串(一列),分配ID,并将ID压入IDmap[i]
    			{
    				IDmap[i].push_back(ID(s));
    				s.clear();
    			}
    		}
    	}
    } 
    
    void solve()
    {
    	int x, y, c1, c2, r;
    	for (c1 = 0; c1 < m; c1++)
    	for (c2 = c1 + 1; c2 < m; c2++)
    	{
    		findrow.clear();
    		for (r = 0; r < n; r++)
    		{
    			x = IDmap[r][c1]; y = IDmap[r][c2];
    			node t(x, y);
    			if (!findrow.count(t)) findrow[t] = r;
    			else
    			{
    				cout << "NO" << endl;
    				cout << findrow[t] + 1 << " " << r + 1 << endl;
    				cout << c1 + 1 << " " << c2 + 1 << endl;
    				return;
    			}
    			
    		}
    	}
    	cout << "YES" << endl;
    }
    
    void ReInit()
    {
    	for (int i = 0; i < n; i++) IDmap[i].clear();
    	IDcache.clear(); Scache.clear();
    }
    
    int main()
    {
    	while (cin >> n >> m)
    	{
    		input();
    		solve();
    		ReInit();
    	}
    	return 0;
    }


  • 相关阅读:
    最短路详解
    树状数组基础
    并查集初步
    python shell的交互模式和文本编辑模式
    基于python的selenium自动化测试环境搭建
    Nagios基本搭建
    mysql错误代码对照表较完整
    搭建phpMyAdmin
    Cent OS 7 搭建MySQL
    详解封装源码包成RPM包
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789441.html
Copyright © 2011-2022 走看看