USACO Feed Ratios 解题报告

/*
ID: thestor1
LANG: C++
TASK: ratios
*/
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cassert>
#include <string>
#include <algorithm>

using namespace std;

int gcd(int a, int b)
{
	if(b == 0)
	{
		return a;
	}
	return gcd(b, a % b);
}

const int large = 1000000;
int main()
{
	FILE *fin  = fopen ("ratios.in", "r");
	FILE *fout = fopen ("ratios.out", "w");
	//freopen("log.txt", "w", stdout);

	double matrix[3][4];
	fscanf(fin, "%lf %lf %lf", &matrix[0][3], &matrix[1][3], &matrix[2][3]);
	for(int i = 0; i < 3; ++i)
	{
		fscanf(fin, "%lf %lf %lf", &matrix[0][i], &matrix[1][i], &matrix[2][i]);
	}
	/*
	fprintf(stdout, "matrix:\n");
	for(int i = 0; i < 3; ++i)
	{
		for(int j = 0; j <= 3; ++j)
		{
			fprintf(stdout, "%8.4lf\t", matrix[i][j]);
		}
		fprintf(stdout, "\n");
	}
	*/
	for(int c = 0; c < 3; ++c)
	{
		assert(matrix[c][c] != 0);
		double coef = matrix[c][c];
		for(int j = c; j <= 3; ++j)
		{
			matrix[c][j] /= coef;
		}
		for(int i = 0; i < 3; ++i)
		{
			if(i == c)
			{
				continue;
			}
			coef = matrix[i][c];
			for(int j = c; j <= 3; ++j)
			{
				matrix[i][j] -= coef * matrix[c][j];
			}
		}
	/*
		fprintf(stdout, "matrix:\n");
		for(int i = 0; i < 3; ++i)
		{
			for(int j = 0; j <= 3; ++j)
			{
				fprintf(stdout, "%8.4lf\t", matrix[i][j]);
			}
			fprintf(stdout, "\n");
		}
	*/
	}

	for(int n = 1; n <= 100; ++n)
	{
		int i;
		for(i = 0; i < 3; ++i)
		{
			double d = matrix[i][3] * n;
			if(abs((double)((int)(d + 0.5) - d)) > 0.0001)
			{
				break;
			}
		}
		if(i >= 3)
		{
			int i1 = (int)(matrix[0][3] * n + 0.5);
			int i2 = (int)(matrix[1][3] * n + 0.5);
			int i3 = (int)(matrix[2][3] * n + 0.5);
			fprintf(fout, "%d %d %d %d\n", i1, i2, i3, n);
			return 0;
		}
	}
	fprintf(fout, "NONE\n");
	return 0;
}

刚开始想用linear programming中的simplex算法。苦于半天无法下手写程序,且不能确定能求出整数解。于是转为高斯消元,然后搜索1~100能使三个系数都成为整数的最小倍数。

代码前面高斯消元我比较清楚,后面测试的部分是根据题目给的样例猜的,竟然所有的测试点都过了。。。仍然不知所以然。。。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值