UVA 1592 - Database (数据库) By SuCicada

例题5-9 数据库(Database,ACM/ICPC NEERC 2009,UVa1592)
输入一个n行m列的数据库(1≤n≤10000,1≤i≤10),是否存在两个不同行r1,r2和两个
不同列c1,c2,使得这两行和这两列相同(即(r1,c1)和(r2,c1)相同,(r1,c2)和
(r2,c2)相同)。例如,对于如图5-3所示的数据库,第2、3行和第2、3列满足要求。
Sample Input
3 3
How to compete in ACM ICPC,Peter,[email protected]
How to win ACM ICPC,Michael,[email protected]
Notes from ACM ICPC champion,Michael,[email protected]
2 3
1,Peter,[email protected]
2,Michael,[email protected]
Sample Output
NO
2 3
2 3
YES

本家地址


设计存储的结构

[
    {
        (c1.value, c2.value) -> r0.index
    }
]

列表中存储每一行中列列的组合(map存储)。列表的大小会是数据库的列*(列-1)/2。map的键是一个存有2个元素的列表(列表中存的是列值),map的值是对应的行下标。map的大小为总行数。

存储:
我们在存储时,针对每一行进行列的两两组合,然后对每一个组合在当前列组合下标中进行map查找,如果总排列数过完之后,有2个map匹配项,那我们就找到了。

在这里也用到了字符串索引存储的方式。类比指针,我们对每一个字符串给定一个编号,然后存在数据库中的就只是这个编号,而不用存字符串,节省了很大空间。


#include
#include
#include
#include
#include
#include
#include
using namespace std;

/* 
[
    {
        (c1.value, c2.value) -> r0.index
    }
]
*/
vector< map< vector<int>,int> > parquet;
map<string, int> dict;

/* temp of one row */
vector<int> rowTemp;

int X,Y;

char tmp[99];

int getIndexOfStr(string str){
    if(!dict.count(str)){
        dict[str] = dict.size();
    }
    return dict[str];    
}

int calc(int row,int* col1,int* col2){
    vector<int> tuple2;
    int tuple2_index = 0;
    for(int i=0;i<Y;i++){
        for(int j=i+1;j<Y;j++){

            tuple2.clear();
            tuple2.push_back(rowTemp[i]);
            tuple2.push_back(rowTemp[j]);

            // cout<
            if(parquet[tuple2_index].count(tuple2)){
                int row1 = parquet[tuple2_index][tuple2];
                *col1 = i;
                *col2 = j;
                return row1;
            }else{
                parquet[tuple2_index][tuple2] = row;
            }
            tuple2_index++;
        }
    }
    return -1;
}

int main(){
    int a,b;
    while(cin>>a>>b){
        getchar();
        X=a,Y=b;
        /* 新的一组 */
        /* init vector */
        parquet.clear();
        for(int i=0;i<Y*(Y-1)/2;i++){
            map<vector<int>, int> tempMap;
            parquet.push_back(tempMap);
        }
        
        /* 过一行中的一列 */
        int right=0;
        int row1,row2;
        int col1,col2;
        for(int row=0;row<a;row++){
            /* 新的一行开始了 */
            rowTemp.clear();
            char c;
            int i=0,col=0;
            while((c=getchar()) &&c !='\n' && c!=EOF){
                if(c==','){
                    string s(tmp,0,i);
                    rowTemp.push_back(getIndexOfStr(s));
                    
                    col++;
                    i=0;
                }else{
                    tmp[i]=c;
                    i++;
                }
            }
            string s(tmp,0,i);
            rowTemp.push_back(getIndexOfStr(s));

            /* 存入新的一行中的2列组合 */
            if(right==0){
                int ccol1,ccol2;
                int rrow1 = calc(row,&ccol1,&ccol2);
                if(rrow1 != -1){
                    right = 1;
                    col1 = ccol1+1;
                    col2 = ccol2+1;
                    row1 = rrow1+1;
                    row2 = row+1;
                }
            }
            /* 这一行过完了 */
        }
        /* 这一组过完了 */
        if(right){
            cout<<"NO"<<endl;
            cout<<row1<<" "<<row2<<endl;
            cout<<col1<<" "<<col2<<endl;
        }else{
            cout<<"YES"<<endl;
        }
    }
    return 0;
}

// AC at 2020/09/08

ps:这一道题重点在于设计数据库存储方式上,我居然最终求助于刘汝佳,真是太逊了。

你可能感兴趣的:(UVA 1592 - Database (数据库) By SuCicada)