USACO Section 3.2 Feed Ratios(解三元一次方程)

Feed Ratios
1998 ACM Finals, Dan Adkins

Farmer John feeds his cows only the finest mixture of cow food, which has three components: Barley, Oats, and Wheat. While he knows the precise mixture of these easily mixable grains, he can not buy that mixture! He buys three other mixtures of the three grains and then combines them to form the perfect mixture.

Given a set of integer ratios barley:oats:wheat, find a way to combine them IN INTEGER MULTIPLES to form a mix with some goal ratio x:y:z.

For example, given the goal 3:4:5 and the ratios of three mixtures:

        1:2:3
        3:7:1
        2:1:2

your program should find some minimum number of integer units (the `mixture') of the first, second, and third mixture that should be mixed together to achieve the goal ratio or print `NONE'. `Minimum number' means the sum of the three non-negative mixture integers is minimized.

For this example, you can combine eight units of mixture 1, one unit of mixture 2, and five units of mixture 3 to get seven units of the goal ratio:

    8*(1:2:3) + 1*(3:7:1) + 5*(2:1:2) = (21:28:35) = 7*(3:4:5)

Integers in the goal ratio and mixture ratios are all non-negative and smaller than 100 in magnitude. The number of units of each type of feed in the mixture must be less than 100. The mixture ratios are not linear combinations of each other.

PROGRAM NAME: ratios

INPUT FORMAT

Line 1: Three space separated integers that represent the goal ratios
Line 2..4: Each contain three space separated integers that represent the ratios of the three mixtures purchased.

SAMPLE INPUT (file ratios.in)

3 4 5
1 2 3
3 7 1
2 1 2

OUTPUT FORMAT

The output file should contain one line containing four integers or the word `NONE'. The first three integers should represent the number of units of each mixture to use to obtain the goal ratio. The fourth number should be the multiple of the goal ratio obtained by mixing the initial feed using the first three integers as mixing ratios.

SAMPLE OUTPUT (file ratios.out)

8 1 5 7
题意:FJ需要一种饲料是一种含有三种物质的混合饲料,其比例已经给定。FJ买了买了另外三种饲料分别按不同比例含有这三种物质,现在FJ问你能否通过这三种饲料调制成所需要的饲料。如果不能输出NONE,如果可以输出最小的比例。
分析:列三个三元一次的方程:
a1*x+b1*y+c1*z=a*k;
a2*x+b2*y+c2*z=b*k;
a3*x+b3*y+c3*z=c*k;
如果系数行列式等于0,则无解;否则就是有解,k从1开始枚举直到碰见x,y,z都是非负数,就输出x、y、z、k。
View Code
/*
  ID: dizzy_l1
  LANG: C++
  TASK: ratios
*/
#include<iostream>
#include<cstdio>

using namespace std;

int a[4][4],A[4],D[4],x,y,z;
bool flag;

int Count(int aa[4][4])
{
    int t;
    t=aa[1][1]*aa[2][2]*aa[3][3]+aa[1][2]*aa[2][3]*aa[3][1]+aa[1][3]*aa[2][1]*aa[3][2];
    t=t-aa[1][3]*aa[2][2]*aa[3][1]-aa[1][1]*aa[2][3]*aa[3][2]-aa[1][2]*aa[2][1]*aa[3][3];
    return t;
}

void work(int p)
{
    int i,j,k,t[4][4];
    for(i=1;i<=3;i++) for(j=1;j<=3;j++) t[i][j]=a[i][j];
    for(k=1;k<=3;k++)
    {
        for(i=1;i<=3;i++) t[i][k]=A[i]*p;
        D[k]=Count(t);
        for(i=1;i<=3;i++) for(j=1;j<=3;j++) t[i][j]=a[i][j];
    }
    if(D[1]%D[0]==0&&D[2]%D[0]==0&&D[3]%D[0]==0)
    {
        x=D[1]/D[0];y=D[2]/D[0];z=D[3]/D[0];
        flag=true;
    }
}

int main()
{
    freopen("ratios.in","r",stdin);
    freopen("ratios.out","w",stdout);
    int i,p;
    while(scanf("%d%d%d",&A[1],&A[2],&A[3])==3)
    {
        for(i=1;i<=3;i++)
        {
            scanf("%d%d%d",&a[1][i],&a[2][i],&a[3][i]);
        }
        D[0]=Count(a);
        if(D[0]==0)
        {
            printf("NONE\n");
            continue;
        }
        flag=false;
        p=1;
        while(!flag)
        {
            work(p++);
        }
        if(x>=0&&y>=0&&z>=0)
            printf("%d %d %d %d\n",x,y,z,p-1);
        else
            printf("NONE\n");
    }
    return 0;
}

你可能感兴趣的:(USACO Section 3.2 Feed Ratios(解三元一次方程))