题意:农场有n头奶牛,每头奶牛都有一个产奶周期ti天(ti<=10),每天产奶ai,每天农场都想杀一头奶牛吃,但希望杀产奶最小的一头,如果有多头产奶最小,则那天将不杀。现问最后剩下几头,杀最后一头牛是第几天。
#include<cstdlib>
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include <algorithm>
#include<set>
#include<queue>
#define LL long long
#define inf 0x7fffffff
#define E 1e-9
#define M 100
#define N 1005
using namespace std;
int ma[N][3000];
int vis[N];
int num[N];
int minv[251];
int gcd(int a,int b)
{
if(a<b)
swap(a,b);
int t;
while(b)
{
t=a%b;
a=b;
b=t;
}
return a;
}
int lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
void add(int a[],int k,int m)
{
int s=m/k-1;
for(int i=0; i<s; i++)
{
memcpy(a+k*(i+1),a,k*sizeof(int));
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ex.in","r",stdin);
#endif
int ncase,n;
scanf("%d",&ncase);
while(ncase--)
{
memset(vis,0,sizeof(vis));
scanf("%d",&n);
for (int i=0; i<n; i++)
{
scanf("%d",&num[i]);
for (int j=0; j<num[i]; j++)
scanf("%d",&ma[i][j]);
}
int m=1;
for(int i=0; i<n; i++)
m=lcm(m,num[i]);
for(int i=0; i<n; i++)//变为同大小数组
{
add(ma[i],num[i],m);
}
int flag=1;
int time=0,beef=0,ans=0,v,sub;
while(flag)
{
flag=0;
for(int i=0; i<m; i++)
{
++time;
v=300;
for(int j=0; j<n; j++)
if(!vis[j])
{
if(v>ma[j][i])
{
v=ma[j][i];
minv[v]=1;//不用初始化
sub=j;
}
else if(v==ma[j][i])
minv[v]++;
}
if(minv[v]==1)
{
beef++;
vis[sub]=1;
ans=time;
flag=1;
}
}
}
printf("%d %d\n",n-beef,ans);
}
return 0;
}