Uva1592 Database 【map应用】【例题5-9】

题目:Database

题意:n,m大小的字符串,是否存在俩个不同行r1,r2和不同列c1,c2,使得这俩行和这俩列相同!即(r1,c1)和(r2,c1)相同, (r1,c2)和(r2,c2)相同!

思路:只枚举c1和c2,然后从上到下扫描行。每次碰到一个新的行r,把c1,c2作为map的键,r为对应的值存入,当扫描到键值存在时,即为当前行为r2,键值对应的值为r1

这里键需要作一个预处理,将每一个字符串再利用一个map集合给其编号,处理完后整个字符串数组即为整数数组,不同字符串有不同的编号,相同的编号相同。

c1,c2同时为键的话需要用一个pair类型,pair<类型,类型>,它可以将俩个值看作为一个值,make_pair(值,值)是将俩个值放入!

最后要注意的是:使用集合,容器的一定要清空!!!

代码:

#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#include <string.h>
using namespace std;
const int maxn = 10005;
const int maxm = 15;
int number[maxn][maxm];
map<string,int>IDcache;//每个字符串对应的id
map< pair<int,int>,int>scan;//键:c1,c2共同组成,值:r1
vector<string>vtr;
int ID(string str)//给字符串分配编号
{
    if(IDcache.count(str))//此字符串是否存在
        return IDcache[str];//存在,返回它的id
    vtr.push_back(str);//不存在,加入容器
    return IDcache[str] = vtr.size() - 1;//它所在容器的位置即为它的id
}
int main()
{
    int n,m;
    char temp[85];
    while(cin >> n >> m)
    {
        getchar();//吸收回车
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m-1;j++)
            {
                cin.getline(temp,85,',');//以逗号为分隔接收
                string str(&temp[0],&temp[strlen(temp)]);//将字符数组转换成字符串
                number[i][j] = ID(str);//在对应位置编号
            }
            cin.getline(temp,85);
            string str(&temp[0],&temp[strlen(temp)]);
            number[i][m-1] = ID(str);
        }
        int record[4],flag = 0;
        for(int j=0;j<m;j++)
        {
            for(int k=j+1;k<m;k++)
            {
                for(int i=0;i<n;i++)
                {
                    int c1 = number[i][j],c2 = number[i][k];
                    if(scan.count(make_pair(c1,c2)))//当发现集合中出现一次c1,c2值时,说明找到了相同处
                    {
                        record[0] = scan[make_pair(c1,c2)]+1;
                        record[1] = i+1;
                        record[2] = j+1;
                        record[3] = k+1;
                        flag = 1;
                        break;
                    }
                    scan[make_pair(c1,c2)] = i;
                }
                if(flag) break;
                scan.clear();//每次扫描完一遍都得清空!就因为这里挂了N回!!!
            }
            if(flag) break;
        }
        if(flag)
            printf("NO\n%d %d\n%d %d\n",record[0],record[1],record[2],record[3]);
        else
            cout << "YES" << endl;
        /*for(int i=0;i<n;i++){
            for(int j=0;j<m;j++)
                cout << number[i][j];
        cout <<endl;}*/
        //清空集合,容器!
        vtr.clear();
        scan.clear();
        IDcache.clear();
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值