POJ 1166 The Clocks 高斯消元 + exgcd(纯属瞎搞)

根据题意可构造出方程组,方程组的每个方程格式均为:C1*x1 + C2*x2 + ...... + C9*x9 = sum + 4*ki;

高斯消元构造上三角矩阵,以最后一个一行为例:

C*x9 = sum + 4*k,exgcd求出符合范围的x9,其他方程在代入已知的变量后格式亦如此。

第一发Gauss,蛮激动的。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <ctime>

#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long
#define _LL __int64
#define INF 0x3f3f3f3f
#define Mod 6000007

using namespace std;

const int MAXN = 20;

int up[] = {0,4,3,4,3,5,3,4,3,4};

int site[10][5] = {
{0},
{1,2,4,5},
{1,2,3},
{2,3,5,6},
{1,4,7},
{2,4,5,6,8},
{3,6,9},
{4,5,7,8},
{7,8,9},
{5,6,8,9}
};

int Map[10];

LL coe[MAXN][MAXN];
LL sol[MAXN];

void Output()
{
    int i,j;
    for(i = 1;i <= 9; ++i)
    {
        for(j = 1;j <= 10; ++j)
        {
            printf("%lld ",coe[i][j]);
            if(j == 9)
                printf("= ");
        }
        printf("\n");
    }
    puts("");
}

LL Abs(LL x)
{
    if(x < 0)
        return -x;
    return x;
}

LL gcd(LL x,LL y)
{
    if(y == 0)
        return x;
    return gcd(y,x%y);
}

void exgcd(LL a,LL b,LL &x,LL &y)
{
    if(b == 0)
        x = 1,y = 0;
    else
    {
        LL x1,y1;
        exgcd(b,a%b,x1,y1);
        x = y1;
        y = x1-a/b*y1;
    }
}

//n为行数,m为列数(包含最后一项)
//return -1无整数解 return 0存在整数解。
int Gauss(int n,int m)
{
    int i,j,k;

    LL T,A,B;

    //Output();

    for(i = 1;i < n; ++i)
    {
        for(j = i+1;j <= n; ++j)
        {
            if(coe[j][i] == 0)
                continue;

            if(coe[i][i] == 0)
            {
                for(k = i;k <= m; ++k)
                    T = coe[i][k],coe[i][k] = coe[j][k],coe[j][k] = T;
                continue;
            }

            T = gcd(coe[i][i],coe[j][i]);
            A = coe[j][i]/T,B = coe[i][i]/T;

            for(k = i;k <= m; ++k)
                coe[j][k] = coe[i][k]*A - coe[j][k]*B;
        }
        //Output();
    }

    LL sum = 0;

    for(i = n;i >= 1; --i)
    {
        sum = coe[i][m];
        for(j = m-1;j > i; --j)
            sum -= coe[i][j]*sol[j];

        LL A = coe[i][i],B = 4,C = sum;
        LL x,y;

        exgcd(A,B,x,y);
        //cout<<"A = "<<A<<" B = "<<B<<" C = "<<C<<" x = "<<x<<" y = "<<y<<endl;
        x *= C/gcd(A,B);
        //cout<<"x = "<<x<<endl;
        y = B/gcd(A,B);
        x = (x-x/y*y + Abs(y))%Abs(y);
        sol[i] = x;

        //cout<<"i = "<<i<<" x = "<<x<<endl;

//        if(sum%coe[i][i] != 0)
//            return -1;//此时无整数解
//        sol[i] = sum/coe[i][i];
    }

    return 0;
}

int main()
{
    int i,j;

    for(i = 1;i <= 9; ++i)
        scanf("%d",&Map[i]);

    memset(coe,0,sizeof(coe));

    for(i = 1;i <= 9; ++i)
    {
        for(j = 0;j < up[i]; ++j)
        {
            coe[site[i][j]][i] = 1;
        }
    }

    for(i = 1;i <= 9; ++i)
        coe[i][10] = (4-Map[i])%4;

    if(-1 == Gauss(9,10))
        while(0)
        ;

    bool mark = true;

    for(i = 1;i <= 9;++i)
    {
        for(j = 0;j < sol[i]; ++j)
        {
            if(mark == false)
                printf(" ");
            else
                mark = false;
            printf("%d",i);
        }
    }

    return 0;
}

POJ 1166 The Clocks 高斯消元 + exgcd(纯属瞎搞)

时间: 2024-10-18 00:42:42

POJ 1166 The Clocks 高斯消元 + exgcd(纯属瞎搞)的相关文章

[ACM] POJ 2947 Widget Factory (高斯消元)

Widget Factory Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 4436   Accepted: 1502 Description The widget factory produces several different kinds of widgets. Each widget is carefully built by a skilled widgeteer. The time required to

poj 1830 开关问题 高斯消元

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

POJ 1830 开关问题 高斯消元,自由变量个数

http://poj.org/problem?id=1830 如果开关s1操作一次,则会有s1(记住自己也会变).和s1连接的开关都会做一次操作. 那么设矩阵a[i][j]表示按下了开关j,开关i会被操作一次,记得a[i][i] = 1是必须的,因为开关i操作一次,本身肯定会变化一次. 所以有n个开关,就有n条方程, 每个开关的操作次数总和是:a[i][1] + a[i][2] + ... + a[i][n] 那么sum % 2就代表它的状态,需要和(en[i] - be[i] + 2) % 2

poj 2947 Widget Factory (高斯消元,解模线性方程)

链接:poj 2947 题意:生产一些零件,已知零件种数,记录条数 记录只记录了某次生产从周几开始,周几结束,以及生产了哪些产品. 每件商品生产所需天数为3-9天. 求每样产品需要多少天才能完成. 若无解输出Inconsistent data. 有无穷解输出Multiple solutions. 有唯一解,输出其解 分析:根据题目所给信息,可以列出同余方程组,再根据高斯消元求解, 但还得判断是无解,无穷解,还是唯一解 1.系数矩阵的秩若与增广矩阵的秩不相等,则无解,否则有解 2.若有解,若增广矩

poj1166--The Clocks(高斯消元)

题目链接:点击打开链接 题目大意:给出9个时钟初始的时间,要求全部调到12点,有9中操作,问应该怎么操作. 每种操作只能出现0次.1次.2次.3次,而时钟需要调的次数也是给定的,直接列方程组,高斯消元 #include <cstdio> #include <cstring> #include <algorithm> using namespace std ; char str[9][10] = { "ABDE","ABC",&qu

poj 2947 Widget Factory(高斯消元)

description The widget factory produces several different kinds of widgets. Each widget is carefully built by a skilled widgeteer. The time required to build a widget depends on its type: the simple widgets need only 3 days, but the most complex ones

Poj 2947 widget factory (高斯消元解同模方程)

题目连接: http://poj.org/problem?id=2947 题目大意: 有n种类型的零件,m个工人,每个零件的加工时间是[3,9],每个工人在一个特定的时间段内可以生产k个零件(可以相同种类,也可以不同种类),问每种零件生产一个出来需要的时间? 解题思路: 给出的时间段是从周几到周几,并没有给出具体的时间段,因此在计算过程中要进行取模,还有就是对每个零件要在题目要求的范围内进行枚举. ps:如果求出来的增广矩阵是n*n的,但是某个零件在[3,9]之间没有合理的解,也是无解的. 1

POJ 3532 Resistance(高斯消元+基尔霍夫定理)

[题目链接] http://poj.org/problem?id=3532 [题目大意] 给出n个点,一些点之间有电阻相连,求1~n的等效电阻 [题解] 有基尔霍夫定理:任何一个点(除起点和终点)发出的电流和与接收的电流和相等. 由ΣAi=0可以得到Σ(Ui-Uj)/Rij=0,Σ(U1-Uj)/R1j=1,Σ(Un-Uj)/Rnj=-1 我们设电流为1A,终点电势为0列关于电势的方程组,最后的等效电阻就是起点和终点的电势差除以总电流 [代码] #include <cstdio> #inclu

POJ 1222-EXTENDED LIGHTS OUT(高斯消元求解异或方程组)

题目地址:POJ 1222 题意:有一个5*6的矩阵,每个位置都表示按钮和灯,1表示亮,0表示灭.每当按下一个位置的按钮,它和它周围灯的状态全部翻转(题目中给出如何影响),问在这样的一个方阵中按下哪些按钮可以把整个方阵都变成灭的,这时1表示按了,0表示没按. #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <iostream>