zoukankan      html  css  js  c++  java
  • Wunder Fund Round 2016 (Div. 1 + Div. 2 combined) F. Double Knapsack 鸽巢原理 构造

    F. Double Knapsack

    题目连接:

    http://www.codeforces.com/contest/618/problem/F

    Description

    You are given two multisets A and B. Each multiset has exactly n integers each between 1 and n inclusive. Multisets may contain multiple copies of the same number.

    You would like to find a nonempty subset of A and a nonempty subset of B such that the sum of elements in these subsets are equal. Subsets are also multisets, i.e. they can contain elements with equal values.

    If no solution exists, print  - 1. Otherwise, print the indices of elements in any such subsets of A and B that have the same sum.

    Input

    The first line of the input contains a single integer n (1 ≤ n ≤ 1 000 000) — the size of both multisets.

    The second line contains n integers, denoting the elements of A. Each element will be between 1 and n inclusive.

    The third line contains n integers, denoting the elements of B. Each element will be between 1 and n inclusive.

    Output

    If there is no solution, print a single integer  - 1. Otherwise, your solution should be printed on four lines.

    The first line should contain a single integer ka, the size of the corresponding subset of A. The second line should contain ka distinct integers, the indices of the subset of A.

    The third line should contain a single integer kb, the size of the corresponding subset of B. The fourth line should contain kb distinct integers, the indices of the subset of B.

    Elements in both sets are numbered from 1 to n. If there are multiple possible solutions, print any of them.

    Sample Input

    10
    10 10 10 10 10 10 10 10 10 10
    10 9 8 7 6 5 4 3 2 1

    Sample Output

    1
    2
    3
    5 8 10

    Hint

    题意

    给你a集合和b集合,两个集合里面都恰好有n个数,每个数都是在[1,n]范围内的数

    然后你需要找到a集合的一个子集,b集合的一个子集,使得这两个子集的和相同

    然后输出出来。

    题解:

    令Ai = a0+a1+...+ai,Bi = b0+b1+...+bi

    其中A0 = 0,B0 = 0;

    我们假设An<Bn,那么对于每个Ai,我们都可以找到一个最大的j,使得Ai-Bj>=0

    显然有(n+1)对Ai-Bj,且0<=(Ai-Bj)<=n-1

    根据鸽巢原理,显然可以找到两对Ai-Bj = Ai'-Bj'

    所以只要输出这两队就好了

    边扫边存下来就好了

    然后这道题就结束了

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e6+7;
    const long long inf = 1e9;
    long long a[maxn],b[maxn];
    pair<int,int>d[maxn*2];
    
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        for(int i=1;i<=n;i++)
            scanf("%lld",&b[i]);
        for(int i=0;i<maxn*2;i++)
            d[i]=make_pair(inf,inf);
        d[maxn]=make_pair(1,1);
        int p1=1,p2=1,now=0;
        while(1)
        {
            if(now<=0)now+=a[p1++];
            else now-=b[p2++];
            if(d[now+maxn].first!=inf)
            {
                printf("%d
    ",p1-d[now+maxn].first);
                for(int i=d[now+maxn].first;i<p1;i++)
                    printf("%d ",i);
                printf("
    ");
                printf("%d
    ",p2-d[now+maxn].second);
                for(int i=d[now+maxn].second;i<p2;i++)
                    printf("%d ",i);
                printf("
    ");
                return 0;
            }
            d[now+maxn]=make_pair(p1,p2);
        }
    }
  • 相关阅读:
    附加数据库对于服务器失败5120
    c#程序调试没有问题,Ctrl+F5运行就挂
    c#让某个窗体一直显示于桌面最上方
    c#调用GrADS
    备份对于服务器“”失败,加载的介质已格式化为支持1个介质簇,但根据指定的备份设备,应支持2个介质簇
    Assembly.Load()出错
    对控件部分的截图和录像
    创建oracle本地数据库步骤详解
    基于windows的resin配置
    oracle 插入记录,字段自动获取当前系统时间(YYYY-MM-DD HH24:MI:SS)
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5213186.html
Copyright © 2011-2022 走看看