GCJ EMEA Semifinal 2008 Painting a Fence

Problem

You need to hire some people to paint a fence. The fence is composed of 10000 contiguous sections, numbered from 1 to 10000.

You get some offers from painters to help paint the fence. Each painter offers to paint a contiguous subset of fence sections in a particular color. You need to accept a set of the offers, such that:

  • Each section of the fence is painted.
  • At most 3 colors are used to paint the fence.

If it is possible to satisfy these two requirements, find the minimum number of offers that you must accept.

Input

  • One line containing an integer T, the number of test cases in the input file.

For each test case, there will be:

  • One line containing an integer N, the number of offers.
  • N lines, one for each offer, each containing "C A B" where C is the color, which is an uppercase string of up to 10 letters, A is the first section and B is the last section to be painted. 1 ≤ AB ≤ 10000.

Output

  • T lines, one for each test case in the order they occur in the input file, each containing the string "Case #X: Y", where X is the case number, and Y is the number of offers that need to be accepted, or "Case #X: IMPOSSIBLE" if there is no acceptable set of offers.

Limits

1 ≤ T ≤ 50

Small dataset

1 ≤ N ≤ 10

Large dataset

1 ≤ N ≤ 300

Sample


Input
 

Output
 
5
2
BLUE 1 5000
RED 5001 10000
3
BLUE 1 6000
RED 2000 8000
WHITE 7000 10000
4
BLUE 1 3000
RED 2000 5000
ORANGE 4000 8000
GREEN 7000 10000
2
BLUE 1 4000
RED 4002 10000
3
BLUE 1 6000
RED 4000 10000
ORANGE 3000 8000
Case #1: 2
Case #2: 3
Case #3: IMPOSSIBLE
Case #4: IMPOSSIBLE
Case #5: 2

 

枚舉顏色數+Greedy就可以了

 

Code:

 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<map>

using namespace std;
int head[305];
typedef struct 
{
    int f;
    int e;
    int co;
    int next;
}C;

C offer[305];
C ss[305];
int cmp(const void *a, const void *b)
{
    C x = *((C*)a);
    C y = *((C*)b);
    if(x.f!=y.f)
        return x.f-y.f;
    return x.e-y.e;
}
int main(void)
{
    map<string,int> color;
    int T,N;
    scanf("%d",&T);
    int tc = 1;
    int i,j,k;
    char s[30];
    int f,e;
    int cn;
    C tmp;
    int on;
    int tans;
    while(T--)
    {
        scanf("%d",&N);
        color.clear();
        on =0;
        memset(head,-1,sizeof(head));
        cn = 1;
        for(i=1;i<=N;i++)
        {
            scanf("%s %d %d",s,&f,&e);
            string x(s);
            if(color[x]==0)
            {
                color[x] = cn++;
            }
            offer[on].f = f;
            offer[on].e = e;
            offer[on].co = color[x];
            offer[on].next = head[color[x]];
            head[color[x]] = on++;
        }
        int ans = 1e8;
        /*1*/
        int l;
        int sn = 0;
        for(i=1;i<cn;i++)
        {
            sn = 0;
            for(j=head[i];j!=-1;j=offer[j].next)
            {
                ss[sn++] = offer[j];
            }
            
            qsort(ss,sn,sizeof(ss[0]),cmp);
            int cr = 0;
            int cl = 0;
            tans = 0;
            for(j=0;j<sn;j++)
                if(ss[j].f<=cr+1)
                {
                    int j1 = j;
                    int tr = cr;
                    while(ss[j1].f<=cr+1&&j1<sn)
                    {
                        if(ss[j1].e>tr)
                            tr = ss[j1].e;
                        j1++;
                    }
                    if(tr>cr)
                    {    
                        
                        cr = tr;
                        cl = ss[j1-1].f;
                        tans ++;
                    }
                    j = j1-1;
                    
                }
            
            if(cr>=10000&&tans<ans)
                ans = tans;
        }
        /*2*/
        for(i=1;i<cn;i++)
            for(j=i+1;j<cn;j++)
            {
                sn = 0;
                for(k=head[i];k!=-1;k=offer[k].next)
                {
                    ss[sn++] = offer[k];
                }
                for(k=head[j];k!=-1;k=offer[k].next)
                {
                    ss[sn++] = offer[k];
                }
                
                qsort(ss,sn,sizeof(ss[0]),cmp);
                int cr = 0;
                int cl = 0;
                tans = 0;
                
                for(k=0;k<sn;k++)
                    if(ss[k].f<=cr+1)
                    {
                
                    int k1 = k;
                    int tr = cr;
                    while(ss[k1].f<=cr+1&&k1<sn)
                    {
                        if(ss[k1].e>tr)
                            tr = ss[k1].e;
                        k1++;
                    }
                    
                    if(tr>cr)
                    {    
                        cr = tr;
                        cl = ss[k1-1].f;
                        tans ++;
                    }
                    k = k1-1;
                    }
                
            
                if(cr>=10000&&tans<ans)
                    ans = tans;
            }
        /*3*/
        for(i=1;i<=cn;i++)
            for(j=i+1;j<=cn;j++)
                for(k=j+1;k<=cn;k++)
                {
                    sn = 0;
                    for(l=head[i];l!=-1;l = offer[l].next)
                    {
                        ss[sn++] = offer[l];
                    }
                    for(l=head[j];l!=-1;l = offer[l].next)
                    {
                        ss[sn++] = offer[l];
                    }
                    for(l=head[k];l!=-1;l = offer[l].next)
                    {
                        ss[sn++] = offer[l];
                    }
                    qsort(ss,sn,sizeof(ss[0]),cmp);
                    int cr = 0;
                        int cl = 0;
                        tans = 0;
                        for(l=0;l<sn;l++)
                            if(ss[l].f<=cr+1)
                            {
                            int l1 = l;
                            int tr = cr;
                            while(ss[l1].f<=cr+1&&l1<sn)
                            {
                                if(ss[l1].e>tr)
                                    tr = ss[l1].e;
                                l1++;
                            }
                            if(tr>cr)
                            {    
                                cr = tr;
                                cl = ss[l1-1].f;
                                tans ++;
                            }
                            l = l1-1;
                            }
                        if(cr>=10000&&tans<ans)
                            ans = tans;
                }
        
        printf("Case #%d: ",tc++);
        if(ans==1e8)
            printf("IMPOSSIBLE\n");
        else
            printf("%d\n",ans);
        
    }
    
    
    
    return 0;
}
arrow
arrow
    全站熱搜

    zxc10806 發表在 痞客邦 留言(0) 人氣()