A Big Dinner

来源:互联网 发布:php 2年工作经验招聘 编辑:程序博客网 时间:2024/06/06 12:22

题目描述:

A. A Big Dinner

Time Limit: 1000ms

Memory Limit: 65535KB
64-bit integer IO format: %lld Java class name: Main

Submit Status PID: 24249

As is known to all, an ACM team consists of three members and to know more about each others, they often go to a restaurant to have a big dinner.

Each member ordered himself only one dish, and waited for it. However, the restaurant serves in a strange way. They cooked the meal in a random order. Besides, if some same dishes appear consecutively, the cooks will cook the dishes at the same time.

Given the ordered three dishes, can you output every possible order the restaurant severed.

Input

The first line of the input is T(1 <= T <= 100), which stands for the number of test cases you need to solve.

For each case, there are three integers(the integers are all positive and less than 10) in the single line, which stand for the dish ID for each person.

Output

Every case contains one line with three integer standing for the kinds of ordered dishes.

For every test case, you should output “Case #t:” in the first line, where t indicates the case number and counts from 1. Then output all the possible order the restaurant can serve in the ascending order.

Sample Input

2
2 1 2
1 7 5

Sample Output

Case #1:
1 2 2
2 1 2
2 2 1
Case #2:
1 5 7
1 7 5
5 1 7
5 7 1
7 1 5
7 5 1

题解:

贪心,从size最大的物品开始考虑。如果能平分则平分,不能平分就找size比它小的物品凑出和它相同的size。如果能凑出来则接着做,不能凑出来则把剩下所有物品都给另外一个人。
赛场上思路猜测是这样,然后觉着很对又稍微整了整.难在实现上.
我们的实现:
难点(1):复杂度,搞定i的时候用i之后的权值,感觉是n^2的,然后用了并查集的next数组优化.
难点(2):系数太大.去搞定i的时候,进制需要一直往小的降,那么系数会快速升高,直接爆ll,但是发现如果大于一个limit之后,后面的就一定不能够凑出来,于是设定limit值,算之前先用log判断下.
昂神队的实现:
首先我们不担心复杂度,因为解决i的时候用到了j,那么i和j之间的都变成0了,所以其实就是两个指针的o(n);
那么我们就可以1e^5的次方往下搞,每次只会*2,就不用log预判了.并且设定limit,>limit的都按照limit算,不用提前跳出,那么实现就会简单得多.

重点:

贪心思路的启发.

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <ctype.h>#include <limits.h>#include <cstdlib>#include <algorithm>#include <vector>#include <queue>#include <map>#include <stack>#include <set>#include <bitset>#define CLR(a) memset(a, 0, sizeof(a))#define REP(i, a, b) for(int i = a;i < b;i++)#define REP_D(i, a, b) for(int i = a;i <= b;i++)typedef long long ll;using namespace std;const int maxn = 1e5 + 1000;const ll INF = 300000000000000ll;const int MAX_W = 100000+100;struct info{    int x, a;    info(int _x = 0, int _a = 0)    {        x = _x;        a = _a;    }    bool operator < (const info b) const    {        return a > b.a;    }};info treas[maxn];int n, fa[maxn], ans[maxn], bx[maxn];ll pow2(int x){    ll res = 1;    ll tmp = 2;    while(x)    {        if(x&1)            res = res*tmp;        tmp = tmp*tmp;        x >>= 1;    }    return res;}int getFa(int x){    if(x==fa[x])        return x;    return fa[x] = getFa(fa[x]);}void getUnion(int a, int b){    a = getFa(a);    b = getFa(b);    fa[a] = b;}void solve(){    for(int i = 1; i<=n+1; i++)    {        fa[i] = i;    }    sort(treas+1, treas+1+n);    for(int i = 1;i<=n;i++)        bx[i] = treas[i].x;    int flag = 0, startPos;    int i = 1;    while(i<=n)    {        if(treas[i].x%2 != 0)        {            treas[i].x %= 2;            int j = getFa(i+1);            ll qx = 1, qk = treas[i].a;            while(qx != 0 && j <=n)            {                double tmp = log2((double)INF*1.0/(double)qx*1.0);                int tmpnum = tmp;                tmpnum++;                if(qk-treas[j].a > tmpnum)                {                    flag = 1;                    startPos = i;                    break;                }                else                {                    qx = qx*pow2(qk-treas[j].a);                    qk = treas[j].a;                    if(treas[j].x > qx)                    {                        treas[j].x -= qx;                        qx = 0;                    }                    else                    {                        qx -= treas[j].x;                        treas[j].x = 0;                        getUnion(j, j+1);                        j = getFa(j+1);                    }                }            }            if(qx!=0)            {                flag = 1;                startPos = i;            }        }        i = getFa(i+1);        if(flag != 0)            break;    }    if(flag==0)        printf("0\n");    else    {        memset(ans, 0, sizeof(ans));        ans[treas[startPos].a] = 1;        for(int i = startPos+1;i<=n;i++)        {            int num = bx[i];            int base = treas[i].a;            for(int j = 0;j<31;j++)            {                if((1<<j)&num)                {                    ans[j+base]--;                }            }        }        for(int i = 0;i<=MAX_W;i++)        {            if(ans[i]<0)            {                int tmp = -(ans[i]-1);                tmp /= 2;                ans[i+1] -= tmp;                ans[i] = tmp*2+ans[i];            }        }        int first = 1;        for(int i = MAX_W;i>=0;i--)        {            if(ans[i]==0 && first)                ;            else            {                //printf("---%d----\n", i);                first = 0;                putchar(ans[i]+'0');            }        }        printf("\n");    }}int main(){   // freopen("4Din.txt", "r", stdin);    //freopen("4Dout.txt", "w", stdout);    int ncase;    scanf("%d", &ncase);    for(int _ = 1;_<=ncase;_++)    {        printf("Case #%d: ", _);        scanf("%d", &n);        for(int i = 1;i<=n;i++)        {            scanf("%d%d", &treas[i].a, &treas[i].x);        }        solve();    }    return 0;}
0 0
原创粉丝点击