**
紫书刷题Day1(共勉)
**(第五章起步)
Uva1592(VJ)
题目大意
给出nm的表格,判断是否存在两行,他们对应存在两列相同元素,即(r1,c1)=(r2,c1);(r1,c2)=(r2,c2)
主要思路
暴力枚举的话O(n^4)会TLE,所以不可以暴力枚举。
这题的思路是选取两列再从第一行开始从上往下扫,记录每一行不同列,最后查找是否有相同的行。时间复杂度O(mn*logm)。
具体思路
首先就是紫书前面集合栈所提到的ID分配,这里ID分配可以起到很好的作用对于不同的字符串。
int getID(string x){//给每个字符串分配一个id;
if(id.count(x)){
return id[x];
}else{
id[x]=cnt++;
return id[x];
}
}
其次就是对数据的储存,选择用vector的二维数组储存。
vector<int> table[10005];
table[i].push_back(getID(s1));
然后就是储存字符串后对遍历时每一行的储存,由于是一行的两列,故这里可以用到pair来储存两列的id然后用map->行。
map<pair<int,int>,int> pos;//记录每个点对应的id构成的坐标->行数;
最后就是一个字符串的处理了,由于输入的字符串是一行且由","隔开,故此处需要分隔字符串,这里我从大佬那里学到了字符串流的方法来分割,即getline()的用法,详情见代码。
getline(cin,s);stringstream ss(s);
while(getline(ss,s1,',')){
table[i].push_back(getID(s1));
}
需要注意的是上面的方法用到了getline那么就需要getchar()来吃掉回车,这也是初始化的好习惯。
废话不说了上代码(菜菜勿喷)
#include<bits/stdc++.h>
using namespace std;
int n, m;
string s, st;
map<string, int> idmp; // 字符串->id
int getId(string s) { // 获取字符串id,若已存在,直接返回,否则分配id
if (idmp.find(s) == idmp.end()) idmp.insert({s, idmp.size()}); // 不存在
return idmp[s];
}
int main() {
while (cin >>n >>m) {
getchar(); vector<int> table[n+1]; idmp.clear(); // 初始化!!!
for (int i = 0; i < n; i ++) {
getline(cin, s); stringstream input(s);
while (getline(input, st, ',')) table[i].push_back(getId(st));
}
bool isPNF = true; // 标记是否为PNF
for (int i = 0; i < m-1 && isPNF; i ++) { // 遍历任意两列
for (int j = i+1; j < m && isPNF; j ++) {
map<pair<int,int>, int> pos; // 两列对应字符串标号->行
for (int k = 0; k < n && isPNF; k ++) { // 每一行
if (pos.find({table[k][i],table[k][j]}) == pos.end()) {
pos[{table[k][i],table[k][j]}] = k;
}
else {
printf("NO\n%d %d\n%d %d\n", pos[{table[k][i],table[k][j]}]+1, k+1, i+1, j+1);
isPNF = false;
}
}
}
}
if (isPNF) printf("YES\n");
}
return 0;
}
有无大佬可以看一下下面的码错在哪了
#include<bits/stdc++.h>
using namespace std;
map<string,int> id;
vector<int> table[10005];
int cnt=0;//用于记录已经有多少个不同的字符串了;
int getID(string x){//给每个字符串分配一个id;
if(id.count(x)){
return id[x];
}else{
id[x]=cnt++;
return id[x];
}
}
void solve(int n,int m){
for(int i=0;i<m;i++){
for(int j=m-1;j>i;j--){
map<pair<int,int>,int> pos;//记录每个点对应的id构成的坐标->行数;
for(int k=0;k<n;k++){
if(pos.count({table[k][i],table[k][j]})){
cout<<"NO"<<endl;
cout<<pos[{table[k][i],table[k][j]}]+1<<k+1<<endl;
cout<<i+1<<j+1<<endl;
return;
}else{
pos[{table[k][i],table[k][j]}]=k;
}
}
}
}
cout<<"YES"<<endl;
return;
}
int main(){
string s,s1;
int n,m;
while(cin>>n>>m){
getchar();id.clear();cnt=0;table[10005].clear();//初始化
for(int i=0;i<n;i++){
getline(cin,s);stringstream ss(s);
while(getline(ss,s1,',')){
table[i].push_back(getID(s1));
}
}
solve(n,m);
}
system("pause");
return 0;
}