37分蒟蒻求调!
查看原帖
37分蒟蒻求调!
473904
Miracle516楼主2025/1/9 22:19

原来我这个蒟蒻不会什么高端技巧吧/(ㄒoㄒ)/~~

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
int m,n,c[21][21],t[21][21],o[21],a[21][8001]={0},k[21][21],ti=1;
/*
c[i][j]表示第i个零件的第j个工序由第c[i][j]个机器来完成(见输入)
t[i][j]表示第i个零件的第j个工序完成需要t[i][j]的时间(见输入)
o[i]表示第i个零件已经进行到了o[i]个工序
a[i][j]用来模拟题目表格:第i个机器的第j秒时间是否被占用了
k[i][j]表示第i个零件的第j个工序还剩下k[i][j]秒才完成
ti表示当前时间
*/
queue <int> order;//给定的顺序
void input(){
	//输入
	for(int i=0;i<21;i++)o[i]=1;
	scanf("%d%d",&m,&n);
	int _;
	for(int i=0;i<m*n;i++){
		scanf("%d",&_);
		order.push(_);
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++)scanf("%d",&c[i][j]);
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++)scanf("%d",&t[i][j]);
	}
}
void output(){
	//输出:将剩下的时间中还需要加工的时间最大值加起来就是答案
	int extra=0;
	for(int i=0;i<=20;i++){
		for(int j=0;j<=20;j++){
			if(k[i][j])extra=max(extra,k[i][j]);
		}
	}
	printf("%d",ti+extra-1);
}
bool check(int e,int f){
	//检查第e个零件在第j个工序前是否都已经完成
	for(int i=1;i<f;i++){
		if(k[e][i]>0)return false;
	}
	return true;
}
void work(){
	//时间过了一秒…每一个正在加工零件剩余的时间都-1
	ti++;
	for(int i=1;i<=20;i++){
		for(int j=1;j<=20;j++){
			if(k[i][j])k[i][j]--;
		}
	}
}
int main(){
	input();
	/*
    思路:
    拿出顺序中的首个零件,判断是否可以加工:
    T用于循环每个零件确保同一秒可能有多个零件同时开始加工
    如果不可以加工就把这个零件放到末尾
    如果可以加工就拿出来加工:
    将剩余时间标记,该机器后面的时间都被占用了,并且该零件下一次要做下一个工序了
    每次循环后,更新时间
	*/
	while(!order.empty()){
		int T=order.size();
		while(T--){//看是否会有多台机器同时工作
			int N=order.front(),machine=c[N][o[N]];//N是待加工零件、machine是这个零件希望被哪个机器加工
			order.pop();//先把它踢出队列
			if(!a[machine][ti]&&check(N,o[N])){//同时满足:机器这一秒是空闲的并且该零件前面工序已完成
				k[N][o[N]]=t[N][o[N]];//标记该零件剩余完成时间
				for(int i=0;i<t[N][o[N]];i++)a[machine][ti+i]=1;//该机器的后面几秒钟都被占用了
				o[N]++;//零件可进入下一个工序加工
			}else order.push(N);//做不了这个工序,放回
		}
		work();
	}
 	output();
	return 0;
}
2025/1/9 22:19
加载中...