高效算法设计专项:UVa 10125

来源:互联网 发布:网络运营商自动选择 编辑:程序博客网 时间:2024/05/16 17:51

暴力枚举显然会TLE。Lrj书里介绍了中途相遇法,用map实现了一下,就是先用O(n^2)建立一个a+b到一个整数的映射,然后再用O(n^2)枚举d-c就可以在O(n^2)复杂度下解决该问题了。需要注意的是a、b、c、d不能重复,这里我用map<int,vector<int>>实现以判重。只不过具体代码比较丑……

#include <iostream>#include <fstream>#include <cstring>#include <cstdio>#include <map>#include <algorithm>#include <vector>using namespace std;#define M 1010int n;int a[M];map<int,vector<int> > table;int judge(int a,int b){    int a1=a/2000,a2=a%2000;    int b1=b/2000,b2=b%2000;    if(a1==b1) return 0;    if(a1==b2) return 0;    if(a2==b1) return 0;    if(a2==b2) return 0;    return 1;}int main(){    freopen("in.txt","r",stdin);    while(cin>>n)    {        if(!n) break;        table.clear();        for(int i=0;i<n;i++) cin>>a[i];        sort(a,a+n);        for(int i=0;i<n;i++)            for(int j=i+1;j<n;j++)            {                table[a[i]+a[j]].push_back(i*2000+j);            }        int ans=1<<30;        for(int i=n-1;i>=0;i--)        {            for(int j=i-1;j>=0;j--)            {                int tmp=a[i]-a[j];                if(table.count(tmp))                {                    for(int k=0;k<table[tmp].size();k++)                    {                        if(judge(i*2000+j,table[tmp][k]))                        {                            ans=a[i];                            break;                        }                    }                }                if(ans!=1<<30) break;            }            if(ans!=1<<30) break;        }        if(ans==1<<30) cout<<"no solution"<<endl;        else cout<<ans<<endl;    }    return 0;}


原创粉丝点击