ACM竞赛学习整理--Gauss求解POJ1166

这道题目和1830比较类似,1830是求解的个数,这道题目相当于求线性方程组的整数解。

题目主要内容:有9个钟,其中9个操作方法来扳动上面的指针,每个操作每次只能把指针移动90度,且每个操作是对一组钟进行操作(即执行每个操作之后有几个钟的状态被改变了90度而不是单独某个钟的状态改变了90度)。操作与其影响的钟的对应表如表一所示:
在这里插入图片描述

表一

题目要求的是给出这9个钟的初始状态(0表示指向12点,1表示指向3点,2表示指向6点,3表示指向6点)用操作1-9采用最少的移动次数操作这些钟,使它们都指向12点。

思路:根据操作与钟表的关系我们可以构造一个关系矩阵,如表二所示
在这里插入图片描述

行表示钟,列表示操作,例如,操作1,2,4被采用之后A都会受到影响,移动一步(即90度)。所以题目的意思就是求操作1-9都被操作了多少次,使得每个钟表从初始状态被调整到12点的那个状态,即每个钟表的状态变化=操作1操作次数+操作2操作次数+…+操作9*操作次数。

在这里插入图片描述

#include <iostream>
#include <math.h>
#include<fstream>
#include<cstdlib>
using namespace std;
 
class Mat {
public:
	Mat(int x, int y, double d[]) {
		rows = x;
		cols = y;
		if (x<y - 1)
			cout << "Not enough" << endl;
		int c = 0;
		for (int i = 0; i<x; i++) {
			for (int j = 0; j<y; j++) {
				data[i][j] = d[c];
				c++;
			}
		}
 
	}
	void print();
	int matcols();
	int matrows();
	void gauss();
	void change(int x);
	void result();
	void value();
	void threeDeterminant();
private:
	int rows;
	int cols;
	double data[200][200];
 
};
 
void Mat::print() {
	for (int i = 0; i<rows; i++) {
		for (int j = 0; j<cols; j++) {
			cout.width(4);
			cout << data[i][j] << " ";
		}
		cout << endl;
	}
	cout << endl;
}
 
int Mat::matcols() {
	return cols;
}
 
int Mat::matrows() {
	return rows;
}
 
void Mat::gauss() {
	double m = 0;
	double flag = 0;
	for (int i = 0; i<rows; i++) {
		change(i);
		print();
		if (data[i][i] != 0) {
			for (int j = i + 1; j<rows; j++) {
				//m = 1;
				if (data[j][i] == 0)
					continue;
				m = fabs(1.0 * data[i][i] / data[j][i]);
				
				cout<<data[i][i];
					cout<<endl;
				cout<<data[j][i];
				cout<<endl;
 
				if ((data[j][i] > 0 && data[i][i] > 0) || (data[j][i] < 0 && data[i][i] < 0)) {
					flag = 1;
				}
				else
				{
					flag = -1;
				}
				for (int k = i; k<cols; k++) {
						data[j][k] = data[j][k] * m - flag*data[i][k];
				}
				print();
			}
		}
	}
}
 
void Mat::change(int x) {
	double temp = 0;
	double max = fabs(data[x][x]);
	int loc = x;
	for (int i = x; i < rows; i++) {
		if (fabs(data[i][x]) > max) {
			max = fabs(data[i][x]);
			loc = i;
		}
	}
	if (x != loc) {
		for (int i = x; i < cols; i++) {
			temp = data[x][i];
			data[x][i] = data[loc][i];
			data[loc][i] = temp;
		}
	}
}

void Mat:: value(){	
	double value = 1;		
	for (int i = 1; i < cols; i++) 
		{
      value = data[i-1][i-1]*value;	
	
	}
		cout << value<< " "; 
      cout<<endl;	
}

void Mat:: threeDeterminant()
{
 double	value = 0;
   value = data[0][0]*data[1][1]*data[2][2]
            + data[1][0]*data[2][1]*data[0][2]
             + data[2][0]*data[0][1]*data[1][2]
            
            - data[2][0]*data[1][1]*data[0][2]
            - data[1][0]*data[0][1]*data[2][2]
             - data[0][0]*data[2][1]*data[1][2];
            
     cout<<"Determinant = "<< value<<endl;      
}

 
void Mat::result() {
	double ans[100] = {0};
	double sum = 0;
 
	for (int i = 1; i < cols; i++) {
		sum = data[cols - 1- i][cols -1 ];
		for (int j = 1; j < i; j++) {
			sum -= ans[cols - j] * data[rows - i][rows - j];
		}
		ans[cols - i] = sum / data[cols-1 - i][cols - 1 - i];
	
	}
	for (int i = 1; i < cols; i++) {
		cout << ans[i] << " ";
	}
}
 
int main(int argc, char** argv) {
	double v[100000] = {};
	int n;
	int cc;	
	ifstream infile("1.txt",ios::in);
	int count =0;
	infile>>n;
	while(infile){
		infile>>cc;
		v[count] = cc;
		count++;
	}
 
	Mat a(n, n+1, v);
	a.print();
//	a.threeDeterminant();
	a.gauss();
	a.print();
	a.result();
	cout<<endl;
    a.value();
	return 0;
}

1.TXT 文件内容
9
1 1 0 1 0 0 0 0 0 12
1 1 1 0 1 0 0 0 0 12
0 1 1 0 0 1 0 0 0 12
1 0 0 1 1 0 1 0 0 12
1 0 1 0 1 0 1 0 1 12
0 0 0 1 0 0 1 1 0 12
0 0 0 0 1 0 1 1 1 12
0 0 0 0 0 1 0 1 1 12

ps: 求解线性方程组的方法有很多,Gauss方法也是手段之一。

原创文章 41 获赞 0 访问量 2061

猜你喜欢

转载自blog.csdn.net/qq_21291397/article/details/103868297