UVA1592 Database

题意:

找(r1,c1)==(r2,c1)和(r1,c2)==(r2,c2);

思路:

1)用四重循环枚举会超时,所以将c1,c2变成一对(一个结构体来node封装)来查找
2)用紫书中的IDcache和cache的思想(相同字符串有相同ID) ,无需多次比较字符串

(注意):
1)每循环两列中所有的c1,c2后要清空result

代码

#include <iostream>
#include <cstdio>
#include <string>
#include <set>
#include <vector>
#include <map>
using namespace std;

struct node
{
    int x,y;
    node(int x,int y):x(x),y(y){}
    bool operator < (const node &r) const
    {
        return x<r.x||(x==r.x&&y<r.y);
    }
};

map<node,int> result; //node的x,y对应两列,int对应他们所在的行
vector<int> rows[10000]; // rows[i][j] 表示i行j列元素在cache中的代表的数字

map<string,int> IDcache;
vector<string> cache;
int ID(string &str)
{
    if(!IDcache.count(str))
    {
        cache.push_back(str);
        return IDcache[str]=cache.size()-1;
    }
    else
        return IDcache[str];
}
int main()
{
    string temp;
    int n,m;
    while(cin>>n>>m)
    {

        cache.clear();
        IDcache.clear();

        for(int i=0;i<n;i++)
        {
            rows[i].clear();
        }

        getchar();   //接收n和m后面的'\n'
        //int num=n*m;
        for(int i=0;i<n;i++)
        {
            getline(cin,temp);  //接收一行数据,
            int pos=0,lastpos=0;
            for(int j=0;j<m;j++)
            {
                pos=temp.find_first_of(',',lastpos);   //从lastpos开始找分隔符位置,返回找到的位置;未找到返回-1
                if(pos==-1)
                {
                    string t=temp.substr(lastpos,pos-lastpos);
                    rows[i].push_back(ID(t));
                    break;
                }
                else
                {
                    string t=temp.substr(lastpos,pos-lastpos);
                    rows[i].push_back(ID(t));
                    lastpos=pos+1;
                }

            }

        }
        int r,c1,c2;
        int flag=0;
        for(int c1=0;c1<m;c1++)
        {

            for(int c2=c1+1;c2<m;c2++)
            {
                result.clear();   //遍历完两列清空一次;否则接着上次循环中保存的值,答案会错
                for(int r=0;r<n;r++)
                {
                    int x=rows[r][c1],y=rows[r][c2];
                    node p(x,y);
                    if(!result.count(p))
                        result[p]=r;
                    else
                    {
                        int r1=result[p];
                        printf("NO\n%d %d\n%d %d\n",r1+1,r+1,c1+1,c2+1);
                        flag=1;
                        break;
                    }

                }
                if(flag==1)
                    break;
            }
            if(flag==1)
                break;
        }
        if(flag==0)
            cout<<"YES"<<endl;
    }



    return 0;
}

超时的代码:

#include <iostream>
#include <cstdio>
#include <string>
#include <set>
#include <vector>
using namespace std;
vector<string> eles;
int main()
{
    string temp;
    int n,m;
    while(cin>>n>>m)
    {
        eles.clear();
        eles.push_back(" ");
        getchar();   //接收n和m后面的'\n'
        //int num=n*m;
        for(int i=1;i<=n;i++)
        {
            getline(cin,temp);  //接收一行数据,
            int pos=0,lastpos=0;
            for(int j=1;j<=m;j++)
            {
                pos=temp.find_first_of(',',lastpos);   //从lastpos开始找分隔符位置,返回找到的位置;未找到返回-1
                if(pos==-1)
                {
                    string t=temp.substr(lastpos,pos-lastpos);
                    eles.push_back(t);
                    break;
                }

                else
                {
                    string t=temp.substr(lastpos,pos-lastpos);
                    eles.push_back(t);
                    lastpos=pos+1;
                }

            }

        }
        int r1,r2,c1,c2;
        int flag=0;
        for(r1=1;r1<=n;r1++) //枚举r1,r2,c1,c2
        {
            for(r2=r1+1;r2<=n;r2++)
            {
                for(c1=1;c1<=m;c1++)
                {
                    for(c2=c1+1;c2<=m;c2++)
                    {
                        if(r1!=r2&&c1!=c2)
                        {
                            int e1=(r1-1)*m+c1,e2=(r2-1)*m+c1;

                            if(eles[e1]==eles[e2])
                            {
                                int e3=(r1-1)*m+c2,e4=(r2-1)*m+c2;
                                if(eles[e3]==eles[e4])
                                {
                                    cout<<"NO"<<endl;
                                    cout<<r1<<' '<<r2<<endl;
                                    cout<<c1<<' '<<c2<<endl;
                                    flag=1;

                                }

                            }
                        }
                        if(flag==1)
                            break;
                    }
                    if(flag==1)
                        break;
                }
                if(flag==1)
                    break;
            }
            if(flag==1)
                break;
        }
        if(flag==0)
            cout<<"YES"<<endl;
    }



    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值