UVA 10125 - Sumsets

        这个题有两种方法,一种是直接暴力搜索,但是也是有技巧的,先给数组排序,然后从最大的数开始搜索,如果能找到3个数和是这个数,直接结束循环,输出这个数。代码如下:(时间是1.618)

#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
    //freopen("in.txt","r",stdin);
    int n,num[1010],flag;
    while(scanf("%d",&n)!=EOF&&n)
    {
        for(int i=0; i<n; i++)
            scanf("%d",&num[i]);
        sort(num,num+n);
        flag=0;
        for(int i=n-1; i>=0; i--)
        {
            for(int j=0; j<n; j++)
            {
                if(i==j)  continue;
                for(int k=0; k<n; k++)
                {
                    if(k==i||k==j)  continue;
                    for(int h=0; h<n; h++)
                    {
                        if(h==i||h==j||h==k)  continue;
                        if(num[i]==num[j]+num[k]+num[h])
                        {
                            printf("%d\n",num[i]);
                            flag=1;
                            break;
                        }
                    }
                    if(flag)  break;
                }
                if(flag)  break;
            }
            if(flag)  break;
        }
        if(!flag)   printf("no solution\n");
    }
    return 0;
}
          第二种时间是0.339,这个是灵活运用a+b+c=d-->a+b=d-c;这样可以先算出a+b,用map<int ,int >vis存的,vis[x]=y表示a+b=x,然后y是结构体数组的下标,结构体中存的是a和b的值,这样是因为a+b+c=d中的四个数是互不相同的,用结构体存起两个加数。代码如下:

#include<cstdio>
#include<cstring>
#include<map>
#include<algorithm>
using namespace std;
typedef struct Node
{
    int a,b;
} Node;
map<int,int>vis; Node node[500005];
int main()
{
    //freopen("in.txt","r",stdin);
    int n,flag,count;
    int num[1005];

    while(scanf("%d",&n)!=EOF&&n)
    {
        for(int i=0; i<n; i++)
            scanf("%d",&num[i]);
        vis.clear();
        count=1;
        sort(num,num+n);
        for(int i=0; i<n; i++)
        {
            for(int j=i+1; j<n; j++)
            {
                int c=num[i]+num[j];
                if(!vis[c])
                {
                    vis[c]=count;
                    node[count].a=num[i];
                    node[count].b=num[j];
                    count++;
                }
            }
        }
        flag=0;
        for(int i=n-1; i>=0; i--)
        {
            for(int j=0; j<n; j++)
            {
                if(i==j)  continue;
                int c=num[i]-num[j];
                if(vis[c])
                {
                    int hg=vis[c];
                    if(node[hg].a!=num[i]&&node[hg].b!=num[i]&&node[hg].a!=num[j]&&node[hg].b!=num[j])
                    {
                        // printf("%d %d %d %d %d\n",hg,node[hg].a,node[hg].b,num[i],num[j]);
                        flag=1;
                        printf("%d\n",num[i]);
                        break;
                    }
                }
            }
            if(flag)   break;
        }
        if(!flag)  printf("no solution\n");
    }
    return 0;

}



                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值