uva 10273 - Eat or Not to Eat?

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=&problem=1214&mosmsg=Submission+received+with+ID+10683084

题意:农场有n头奶牛,每头奶牛都有一个产奶周期ti天(ti<=10),每天产奶ai,每天农场都想杀一头奶牛吃,但希望杀产奶最小的一头,如果有多头产奶最小,则那天将不杀。现问最后剩下几头,杀最后一头牛是第几天。

思路:n头牛产奶周期的最小公倍数G一定小于10!,可以按产奶的周期把奶牛分成10类。然后枚举天数,找出这10类中的最小值和最小值有多少个。(枚举天数的时候,只要在G周期内没有杀牛,就一定不会杀了)

View Code
#include<stdio.h>
#include<string.h>
#include<vector>
#include<set>
#include<map>
#include<algorithm>
using namespace std;
set<int>as[12][11][255];
map<int,int>bs[12][11];
vector<int>cs[1005];
int gcd(int x,int y){return y?gcd(y,x%y):x;}
int main()
{
    int i,j,k,t,n,m,ans1,ans2,idx,g;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(i = 1; i <= 11; ++ i)
        for(j = 0; j < 11; ++ j)
        for(k = 0; k < 255; ++ k)
            as[i][j][k].clear();

        for(i = 1; i <= 11; ++ i)
        for(j = 0; j < 11; ++ j)
        bs[i][j].clear();

        for(i = 1; i <= n; ++ i)
        cs[i].clear();

        g = 1;
        for(i = 1; i <= n; ++ i){
            scanf("%d",&m);
            if(m)g = g / gcd(g,m) * m;
            for(j = 0; j < m; ++ j){
                scanf("%d",&k);
                as[m][j][k].insert(i);
                bs[m][j][k]++;
                cs[i].push_back(k);
            }
        }

        ans1=n; ans2=0;
        int ii;
        i = 1;
        for(ii = 1; ii <= g; ++ ii,++i){
            k = 300; m = 0;
            for(j = 1; j <= 10; ++ j){
                if(bs[j][(i-1)%j].size()==0)continue;
                int ts = bs[j][(i-1)%j].begin()->first;
                if(k>ts){
                    m = as[j][(i-1)%j][ts].size();
                    k = ts;
                    idx = *(as[j][(i-1)%j][ts].begin());
                }else if(k==ts)m += as[j][(i-1)%j][ts].size();
            }

            if(k==300||m^1)continue;
            ii = 0;
            ans1--; ans2 = i;
            k = cs[idx].size();
            for(j = 0; j < k; ++ j){
                int v = cs[idx][j];
                as[k][j][v].erase(idx);
                bs[k][j][v]--;
                if(bs[k][j][v]==0)bs[k][j].erase(v);
            }
        }
        printf("%d %d\n",ans1,ans2);
    }
    return 0;
}

posted on 2012-10-04 10:54  aigoruan  阅读(234)  评论(0)    收藏  举报

导航