POJ 2947 Widget Factory

题意:

有n种饰品,每种的加工时间为3~9天,现在知道m条记录,每条记录形如:开始时间是周几,终止时间是周几,加工出来哪些饰品,各多少件。但是不知道持续了多少周。
求每种饰品的加工时间。

需要判断无解和多解。


 

昨天晚上做到12:20....

显然是裸的同余方程组

无解?和异或方程组一样

多解?

异或方程组用的是高斯约当消元记录now很方便,同余方程高斯消元需要回代怎么办?于是我想到记录一个$pivot[i]$表示第i个方程的关键元,回代什么的用pivot[i]就行了


[update 11:21:16]

昨天晚上思维太混乱了现在看看写的有问题

于是仔细的想了一下:

在消元之后回代之前就可以判断无解和多解啦

进行回代时保证是唯一解

网上的题解太扯了还要什么复制到最后....

然后输入的时候别忘$mod \ 7$

 

516ms好快啊

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=305;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
typedef int Matrix[N][N];
int n,m,P=7;
char s1[5],s2[5];
Matrix a;
int mp[300];
inline int num(char *s){
    if(s[0]=='T') return s[1]=='U'?1:3;
    else if(s[0]=='S') return s[1]=='A'?5:6;
    else return mp[s[0]];
}
int inv[10];
void iniInv(){
    inv[1]=1;
    for(int i=2;i<=P;i++) inv[i]=(-P/i*inv[P%i]%P+P)%P;
}
int now;
void Gauss(){
    now=1;
    for(int i=1;i<=n;i++){
        int j=now;
        while(j<=m&&!a[j][i]) j++;
        if(j==m+1) continue;
        //printf("hi %d %d %d\n",i,now,j);
        if(j!=now) for(int k=1;k<=n+1;k++) swap(a[now][k],a[j][k]);
        for(int j=now+1;j<=m;j++) if(a[j][i]){//printf("jjj %d\n",j);
            int t=a[j][i]*inv[a[now][i]]%P;//printf("t %d\n",t);
            for(int k=i;k<=n+1;k++) a[j][k]=(a[j][k]-a[now][k]*t%P+P)%P;
        }
        now++;
    }
    
    for(int i=1;i<=m;i++) if(a[i][n+1]){
        int f=0;
        for(int j=1;j<=n;j++) if(a[i][j]){f=1;break;}
        if(f==0) {puts("Inconsistent data.");return;}
    }
    if(now<n) {puts("Multiple solutions.");return;}

    for(int i=m;i>=1;i--){
        for(int j=m;j>i;j--) 
            a[i][n+1]=(a[i][n+1]-a[i][j]*a[j][n+1]%P+P)%P;
        a[i][n+1]=a[i][n+1]*inv[a[i][i]]%P;
    }
    for(int i=1;i<=n;i++) printf("%d%c",a[i][n+1]<3?a[i][n+1]+P:a[i][n+1],i==n?'\n':' ');
}
void solve(){
    //printf("now %d\n",now);
    //for(int i=1;i<=m;i++)
        //for(int j=1;j<=n+1;j++) printf("%d%c",a[i][j],j==n+1?'\n':' ');
}

inline void ini(){memset(a,0,sizeof(a));}
int main(){
    freopen("in","r",stdin);
    mp['M']=0;mp['W']=2;mp['F']=4;
    iniInv();
    while(true){
        ini();
        n=read();m=read();
        if(n==0&&m==0) break;
        for(int i=1;i<=m;i++){
            int k=read();scanf("%s%s",s1,s2);
            a[i][n+1]=(num(s2)-num(s1)+1+P)%P;
            while(k--) a[i][read()]++;
            for(int j=1;j<=n+1;j++) a[i][j]%=P;
            //printf("a %d\n",i);
            //for(int j=1;j<=n+1;j++) printf("%d%c",a[i][j],j==n+1?'\n':' ');
        }
        Gauss();
    }
}

 

posted @ 2017-02-18 08:44  Candy?  阅读(677)  评论(0编辑  收藏  举报