【高斯消元】AcWing 227. 小部件厂
不仅题意不太清楚而且实现过程还有一堆细节的题目。。Orz
分析
其实这题就是给你 个同余方程,然后有 个变量 (其中 ),记第 个方程第 个变量 (其中 )的个数为 , 为两个给出的日子的间隔天数,则满足:
看到这个形式,自然是考虑使用高斯消元来解决,如果得到的矩阵的秩为 ,当然可以直接得到答案——由于 值域不大,直接对每个变量 进行值的枚举,如果出现了无解情况直接 return
,若每个变量都有解就输出解即可。
但是情况没有这么简单,
-
首先我们要判断:如果 ,那么需要判断是否在 行出现矛盾,因为在高斯消元之后, 必须是 的形式,不是则矛盾。
-
其次,如果矩阵的秩,因为高斯消元之后的矩阵会变为最简阶梯形,记每行的系数不为 的个数为 。
那么对于如果 ,检查是否满足 ;如果 ,两个及以上的变量一定足够使这一行有解,跳过;如果 ,通过枚举该变量的值来检查是否有解,而在这个过程中,如果这个变量已经被求解过且值与现在求的不同,那么矛盾。
最简阶梯形矩阵例子:
// Problem: 小部件厂
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/229/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cerr << #x << ": " << (x) << endl
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define int long long
inline int read(){
int s=0; int x=1;
char ch=getchar();
while(ch<'0' || ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0' && ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
return s;
}
const int N=330, P=7;
int n, m;
int c[N][N], b[N];
map<string, int> mp;
void init(){
mp["MON"]=1, mp["TUE"]=2;
mp["WED"]=3, mp["THU"]=4;
mp["FRI"]=5, mp["SAT"]=6;
mp["SUN"]=7;
}
int get(string a, string b){
return ((mp[b]-mp[a]+1)%P+P)%P;
}
int fpow(int x, int p){
int res=1;
for(; p; p>>=1, x=x*x%P) if(p&1) res=res*x%P;
return res%P;
}
int inv(int x){
return fpow(x, P-2);
}
int get(int x){
return (x%P+P)%P;
}
int res[N];
void guass(){
rep(i,1,n){
rep(j,i,m) if(c[j][i]%P){
rep(k,1,n) swap(c[i][k], c[j][k]);
swap(b[i], b[j]);
}
rep(j,1,m){
if(i==j) continue;
int t=c[j][i]*inv(c[i][i])%P;
rep(k,i,n) c[j][k]-=c[i][k]*t%P, c[j][k]=get(c[j][k]);
b[j]-=b[i]*t;
b[j]=get(b[j]);
}
}
rep(row,n+1,m) if(b[row]) return puts("Inconsistent data."), void();
// no fixed sol
rep(pos,1,n) if(!c[pos][pos]){
rep(i,1,n) res[i]=0;
rep(i,1,n){
int cnt=0, rec, p;
rep(j,1,n) if(c[i][j]) cnt++, rec=c[i][j], p=j;
if(cnt!=1){
if(!cnt && b[i]) return puts("Inconsistent data."), void();
continue;
}
bool ok=false;
rep(val,3,9){
int t=val*rec-b[i];
if(t%P==0){
if(res[p] && res[p]!=val) return puts("Inconsistent data."), void();
res[p]=val;
ok=true;
}
}
if(!ok) return puts("Inconsistent data."), void();
}
return puts("Multiple solutions."), void();
}
bool ok=true;
rep(i,1,n){
int cnt=0, rec;
rep(val,3,9){
int t=val*c[i][i]-b[i];
if(t%P) continue;
cnt++, rec=val;
}
if(!cnt){
puts("Inconsistent data.");
return;
}
if(cnt>1) ok=false;
else res[i]=rec;
}
if(!ok) return puts("Multiple solutions."), void();
rep(i,1,n) printf("%lld ", res[i]);
puts("");
}
void clear(){
rep(i,1,m) rep(j,1,n) c[i][j]=0;
rep(i,1,m) b[i]=0;
}
signed main(){
init();
while(n=read(), m=read(), n || m){
string s1, s2;
rep(i,1,m){
int k; k=read();
cin>>s1>>s2;
b[i]=get(s1, s2);
while(k--){
int ty; ty=read();
c[i][ty]++;
}
}
guass();
clear();
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2021-02-18 【数据结构】线性基