《算法竞赛入门经典》---S5----STL

*UVA  1592---map

大概就是要找出两组位置有相同的string

string查找对比时太慢 所以 map一下  就是不同的二行  对应二列字符串相同

【解】

数据:

How to compete in ACM ICPC,Peter,peter@neerc.ifmo.ru
How to win ACM ICPC,Michael,michael@neerc.ifmo.ru
Notes from ACM ICPC champion,Michael,michael@neerc.ifmo.ru
编号为  
       0 1 2 
       3 4 5
       6 4 5
 因为要找到两对相同的列,四重遍历可以找到 太慢了!!!(r1,c1)=(r2,c1),(r1,c2)=(r2,c2)

考虑将c1,c2两列的内容一起存到map中,所以map的key为(x,y)

【x,y分别代表对应字符串的编号】,map的值为对应的行r1,遍历行就是r2;所以三重遍历即可完成。
原文:https://blog.csdn.net/wowowoc/article/details/40554525?utm_source=copy

//救救孩子 并不太懂val和q那个
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <map>
#define BIG 100100
using namespace std;

map<string,int> IDcache;
map<int,int> ans;
vector<vector<int> >  tab;

int main(){
    int n,m,c1,c2,r,val,tmp,f=0,q;
    string cmd;//存储每条未处理字符串 
    while(cin>>n>>m){
        tab.clear();//编号表 
        IDcache.clear();
        ans.clear();
        f=0;// 
        int t=0,row = n,col = m;
        getchar();
        while(n--)
		{
            getline(cin,cmd);
            string str = "";
            vector<int> line;//中间的工具 
            //cout<<cmd<<endl;
            for(int i=0;i<cmd.size();i++)
			{
                if(cmd[i] != ',') str += cmd[i]; //拆分 
                if(cmd[i] == ',' || i==cmd.size()-1) 
				{
                    if(!IDcache.count(str))IDcache[str] = t++;//编号 
        
                    line.push_back(IDcache[str]);//将每一行处理好的编号先保存 
                    str="";//清空 
                }
            }
            tab.push_back(line);//将处理好的拆分行保存 
        }

        for(c1 = 0;c1< col-1 ;c1++)
		{
            for(c2 = c1+1;c2 < col;c2++)
			{
                val = c1*BIG+c2;//不懂val是干啥的 
                for(r  = 0;r < row;r++)
				{
                    q = tab[r][c1]*BIG+tab[r][c2];//woc? 
                    if(ans.count(q)) {tmp = r;f=1;break;}
                    ans[q] = r;
                }
               if(f==1) break;
               ans.clear();
            }
        if(f==1) break;
        }       
        if(f==0) cout<<"YES"<<endl;
        else{
            cout<<"NO"<<endl;
            cout<<ans[q]+1<<" "<<tmp+1<<endl;
            cout<<val/BIG+1<<" "<<val%BIG+1<<endl;//??????? 
        }

    }
    return 0;
}
//经过队友讲解豁然开朗 bing!
//后边附上自己实操代码吧 还是  orzzzzz

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <map>
#define BIG 100100
using namespace std;

map<string,int> IDcache;
map<int,int> ans;
vector<vector<int> >  tab;

int main(){
    int n,m,c1,c2,r,val,tmp,f=0,q;
    string cmd;//存储每条未处理字符串 
    while(cin>>n>>m){
        tab.clear();//编号表 
        IDcache.clear();
        ans.clear();
        f=0;// 
        int t=0,row = n,col = m;
        getchar();
        while(n--)
		{
            getline(cin,cmd);
            string str = "";
            vector<int> line;//中间的工具 
            //cout<<cmd<<endl;
            for(int i=0;i<cmd.size();i++)
			{
                if(cmd[i] != ',') str += cmd[i]; //拆分 
                if(cmd[i] == ',' || i==cmd.size()-1) 
				{
                    if(!IDcache.count(str))IDcache[str] = t++;//编号 
        
                    line.push_back(IDcache[str]);//将每一行处理好的编号先保存 
                    str="";//清空 
                }
            }
            tab.push_back(line);//将处理好的拆分行保存 
        }

        for(c1 = 0;c1< col-1 ;c1++)
		{
            for(c2 = c1+1;c2 < col;c2++)
			{
                val = c1*BIG+c2;//val就是存储c1 c2       
                for(r  = 0;r < row;r++)
				{
                    q = tab[r][c1]*BIG+tab[r][c2];//懂了 大概就是存储一个数 编号一下防止重复 big要大于命令条数 
                    if(ans.count(q)) {tmp = r;f=1;break;}
                    ans[q] = r;
                }
               if(f==1) break;
               ans.clear();
            }
        if(f==1) break;
        }       
        if(f==0) cout<<"YES"<<endl;
        else{
            cout<<"NO"<<endl;
            cout<<ans[q]+1<<" "<<tmp+1<<endl;
            cout<<val/BIG+1<<" "<<val%BIG+1<<endl;//??????? 
        }

    }
    return 0;
}

 

 


 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值