处理方法:
-
先将所有的字符串用数字进行代替(映射),然后就才能处理。主要就是用“,”区分,这里就不赘述这个了,比较简单。
-
然后再次使用映射将两列进行逐行映射,如果用map.count()确定是否进行映射过来如果映射过了,将结束函数。
整体来看应该可以理解。接下来贴代码
#include<map>
#include<string>
#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
map<string,int> ID_str; //将字符串对应成数字存储起来
vector<int> ID_cln_row[11]; //vector在这里相当于一个二维数组
void judge(int row,int cln,string m) //这个函数就是转换字符转化成数字的函数
{
string str = "";
int cln_len = 0;
for(int j = 0; j <= m.length(); j++)
{
if(m[j] == ',' || j == m.length() ) //将长字符分解开来,以“,”进行区分,最后一个用长度确定
{
// cout << str << endl; //显示分解之后一段一段的字符串(用于个人调试)
if(ID_str.count(str) != 0)
{
ID_cln_row[cln_len].push_back(ID_str[str]); //如果以前出现过则直接储存
}
else
{
ID_str[str] = row*cln+cln_len; //如果没有出现过则赋予新值
ID_cln_row[cln_len].push_back(ID_str[str]); //这里的值是在(列数)cln_len
} //加上当前的行数乘以一行的总列数
cln_len++;
str = "";
}
else
str += m[j];
}
}
int main()
{
int row,cln;
while(cin >> row >> cln)
{
getchar(); //去掉输入流的回车
for(int i = 0;i < 11;i++)
ID_cln_row[i].clear();
ID_str.clear(); //初始化一下,要不然上一次存储将影响这一次
for(int i = 0; i < row; i++)
{
string str;
getline(cin,str); //最好用getline()函数得到一行,要不然cin会以空格就结束
// cout << str<<(str).length()<<endl; //用于调试,查看,
//我就是用这个才看出cin以空格也为结束符
judge(i,cln,str);
}
// for(int i = 0;i<row;i++)
// {
// for(int j = 0; j < cln;j++)
// {
// cout << ID_cln_row[j].at(i);
// }
// cout << endl;
// } //用于查看处理之后的数组字符对应成数字的样子
map<pair<int,int>,int> Pair_ID; //核心代码,两列向下拉的对比
for(int k = 0; k < cln - 1; k++)
for(int i = k+1; i < cln ; i++)
{
for(int j = 0; j < row;j++)
{
int x1,x2;
x1 = ID_cln_row[k].at(j);
x2 = ID_cln_row[i].at(j);
if(Pair_ID.count(make_pair(x1,x2)) == 0) //将向下的每一个不一样的储存起来
Pair_ID[make_pair(x1,x2)] = j+1;
else
{
cout <<"NO"<<endl;
cout << Pair_ID[make_pair(x1,x2)] <<" "<<j+1 <<endl; //行
cout << k+1 <<" "<<i+1 <<endl; //列
goto ss;
}
}
Pair_ID.clear(); //这一点不要忘了,每处理两列之后
//一定要清除一次
} //比如 1 1 1 这种轴对称的如果不清楚
cout << "YES" <<endl; // 0 2 0 也将使程序结束因为1 1存
ss:; // 1 3 1 起来之后,到了另外两列
// 会被认为已经有过了
}
return 0;
}
上面是一些用到的函数,都是C++ STL模板库中比较常见的,都能搜到。