• POJ2947解题报告


    原题链接:POJ2947

    思路:本题是用高斯消元以及同余方程做,但是需要注意整数高斯消元避免使用除法。还需注意同余方程的解的问题、方程式与未知数个数不等问题。

    错误报告:这题总时间花了应该有七八个小时了。第一次做忽略了方程式个数不等于未知数个数时情况,并且对于何时无解、何时多解判断方法错误,在消元方面我使用了最小公倍数(异曲同工哈?)避免消元后出现的小数。今天又用了近四小时更改,发现如下错误:

    • 当某个未知数无系数时,说明该未知数是自由元;
    • 虽然我们是在求同余方程组的高斯消元,但在运算过程中如果对其+7再取模可能会造成结果不同;
    • 当无解时,后k个方程(消元消掉了)未知数系数全部为零,故只需判断其常数项是否为0;
    • 当有解时,由于同余方程的缘故,依次将已求出的未知数带入方程,(由于最后得出来的系数矩阵是个三角矩阵)。

    代码示例:

    #include<iostream>
    #include<string>
    #include<cstdio>
    #include<cstring>
    #include<map>
    using namespace std;
    map<string,int> data;
    const int MAXN = 350;
    int a[MAXN][MAXN];
    int b[MAXN],ans[MAXN];
    int n,m,x,num;
    string s,e;
    void init(){
    	data["MON"] = 1; data["TUE"] = 2;
    	data["WED"] = 3; data["THU"] = 4;
    	data["FRI"] = 5; data["SAT"] = 6;
    	data["SUM"] = 7;
    }
    void solve(){
    	int i = 1,j = 1,l,x,y;
    	while(i <= m && j <= n){
    		for(l = i;l <= m;l++){
    			if(a[l][j])	break;
    		}
    		if(l > m){		//attention!
    			j++; 
    			continue;
    		}
    		for(int k = n;k;k--) swap(a[l][k],a[i][k]);
    		swap(b[l],b[i]);
    		x = a[i][j];
    		for(l = i+1;l <= m;l++){
    			y = a[l][j];
    			for(int k = j;k <= n;k++){
    				a[l][k] = (a[l][k]*x - a[i][k]*y)%7;//attention!
    			}
    			b[l] = (b[l]*x - b[i]*y)%7;//too!
    		}
    		i++,j++;
    	}
    	for(l = i;l <= m;l++)				//attention!
    		if(b[l]){ puts("Inconsistent data."); return; }
    	if(i != j || j < n){ puts("Multiple solutions."); return;}
    	//分别对应变量系数为0、方程数不够未知数个数
    	int k;
    	//for(i = 1;i <= n;i++)	cout << b[i] << " " << a[i][i] << endl;
    	for(i--,j--;i;i--,j--)
    	{
    		for(l=0,k=j+1;k<=n;k++) l+=a[i][k]*ans[k];
    		for(k=3;k<=9;k++)
    			if((a[i][j]*k%7+7)%7==((b[i]-l)%7+7)%7) ans[i]=k;
    	}
    	for(i = 1;i < n;i ++) printf("%d ",ans[i]);
    	cout << ans[i] << endl;
    } 
    int main(){
    	init();
    	while(scanf("%d%d",&n,&m) && n && m){
    		memset(a,0,sizeof a);
    		memset(b,0,sizeof b);
    		memset(ans,0,sizeof ans);
    		for(int i = 1;i <= m;i++){
    			scanf("%d",&num);
    			cin >> s >> e;
    			b[i] = (data[e] - data[s] + 8) % 7;
    			while(num--){
    				scanf("%d",&x);
    				a[i][x]++;
    			}
    			for(int j = 1;j <= n;j++)	a[i][j] %= 7;
    		}
    		solve();
    	}
    }
  • 相关阅读:
    520了,用32做个简单的小程序
    安装 部署 postgresql数据库 搭建主从节点 (业务库)
    年轻就该多尝试,教你20小时Get一项新技能
    谷歌搜索进阶(二)
    谷歌搜索进阶(一)
    Linux进程前后台管理(&,fg, bg)
    VTF/AMROC安装指南
    神经网络学习笔记(三):三种典型的架构
    神经网络学习笔记(二):feedforward和feedback
    神经网络学习笔记(一)
  • 原文地址:https://www.cnblogs.com/long98/p/10352163.html
Copyright © 2020-2023  润新知