LightOJ 1151 Snakes and Ladders 高斯消元

给你一个地图10*10,从1到100,问掷骰子的次数的期望,中间会有传送门从a到b。

高斯消元基础题,学了一发板子,x存放多出来的,a存放系数;

要么是dp[i]=(dp[i+1]+...+dp[i+6]+6)/6;

要么是dp[i]=dp[go[i]];

值得注意的是哪怕是没有dp[i+6]也要加6,因为说了,如果超界那投得次数也要算上。

#include <iostream>
#include <functional>
#include <algorithm>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <utility>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <limits>
#include <memory>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
using namespace std;

#define eps 1e-9
const int MAXN=220;
double a[MAXN][MAXN],x[MAXN];
int equ,var;
int go[110];
//int back[110];
int Gauss()
{
    int i,j,k,col,max_r;
    for(k = 0,col = 0; k < equ && col < var; k++,col++)
    {
        max_r = k;
        for(i = k+1; i < equ; i++)
            if(fabs(a[i][col]) > fabs(a[max_r][col]))
                max_r = i;
        if(fabs(a[max_r][col]) < eps)return 0;
        if(k != max_r)
        {
            for(j = col; j < var; j++)
                swap(a[k][j],a[max_r][j]);
            swap(x[k],x[max_r]);
        }
        x[k]/=a[k][col];
        for(j = col+1; j < var; j++)a[k][j]/=a[k][col];
        a[k][col] = 1;
        for(int i = 0; i < equ; i++)
            if(i != k)
            {
                x[i] -=  x[k]*a[i][k];
                for(j = col+1; j < var; j++)a[i][j] -= a[k][j]*a[i][col];
                a[i][col] = 0;
            }
    }
    return 1;
}

int main()
{
    int i,j,ncas=1;
    int t;
//    double a[110][110];
    scanf("%d",&t);
    while(t--)
    {
        memset(a,0.0,sizeof(a));
        memset(x,0.0,sizeof(x));
        for (int i=0;i<100;i++) x[i]=1;
        memset(go,-1,sizeof(go));
        equ=var=100;

        int all;
        scanf ("%d",&all);
        while (all--)
        {
            int t1,t2;
            scanf ("%d%d",&t1,&t2);
            t1--;
            t2--;
            go[t1]=t2;
        }
        for (int i=0; i<100; i++)
        {
            if (go[i]==-1)
            {
                if (i<=93)
                {
                    a[i][i]=6.0;
                    a[i][i+1]=-1.0;
                    a[i][i+2]=-1.0;
                    a[i][i+3]=-1.0;
                    a[i][i+4]=-1.0;
                    a[i][i+5]=-1.0;
                    a[i][i+6]=-1.0;
                    x[i]=6;
                }
                else if (i==99)
                {
                    a[i][i]=1.0;
                    x[i]=0.0;
                }
                else
                {
                    a[i][i]=(99-i)*1.0;
                    int epx=1;
                    while (i+epx<=99)
                    {
                        a[i][i+epx]=-1.0;
                        epx++;
                    }
                    x[i]=6*1.0;
                }
            }
            else
            {
                a[i][i]=1.0;
                a[i][go[i]]=-1.0;
                x[i]=0;
            }
        }
        Gauss();
        printf ("Case %d: %.10f\n",ncas++,x[0]);
    }
    return 0;
}

posted on 2016-05-02 16:00  very_czy  阅读(233)  评论(0编辑  收藏  举报

导航