202009-3 点亮数字人生
自己写了一遍 不考虑回路的情况,样例能通过,自己测试找不出问题。唉,提交测试0分。
要是以后重刷,再来思考问题吧。。
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
int q,m,n,s;
int input[10010][3000];
int gate[510];//标记该器件是否已得到结果
struct node{
int func;//1-NOT,2-AND,3-OR,4-XOR,5-NAND,6-NOR
vector<int> input,output;
int out;
}fun[510];//记录所有器件
int cal(int func,int a,int b){
switch(func){
case 1:
return ~b;
break;
case 2:
return a&b;
break;
case 3:
return a|b;
break;
case 4:
return a^b;
break;
default:
return 0;
}
}
bool check(){
}
void get_output(int in[3000],int index){
int t;
if(fun[index].func==2) t=1;
else t=0;
for(int i=0;i<fun[index].output.size();i++){
int p=fun[index].output[i];
if(!gate[p]) get_output(in,p);
if(fun[index].func==5){
t=cal(2,t,fun[p].out);
}else if(fun[index].func==6){
t=cal(3,t,fun[p].out);
}else t=cal(fun[index].func,t,fun[p].out);
// cout<<"index:"<<index<<" output_t:"<<t<<" p:"<<p<<endl;
}
for(int i=0;i<fun[index].input.size();i++){
int p=fun[index].input[i];
if(fun[index].func==5) t=cal(2,t,in[p]);
else if(fun[index].func==6) t=cal(3,t,in[p]);
else t=cal(fun[index].func,t,in[p]);
// cout<<"index:"<<index<<" input_t:"<<t<<" p:"<<p<<endl;
}
if(fun[index].func>=5) fun[index].out=cal(1,0,t);
else fun[index].out=t;
// cout<<"\n器件值 "<<index<<" 输出: "<<fun[index].out<<endl;
gate[index]=1;
}
int main(){
cin>>q;
getchar();
while(q--){
cin>>m>>n;
getchar();
string str;
for(int i=1;i<=n;i++){
cin>>str;
if(str=="NOT") fun[i].func=1;
else if(str=="AND") fun[i].func=2;
else if(str=="OR") fun[i].func=3;
else if(str=="XOR") fun[i].func=4;
else if(str=="NAND") fun[i].func=5;
else fun[i].func=6;
int k=0,num;
char c;
cin>>k;
for(int j=0;j<k;j++){//每个器件的输入组成
scanf(" %c%d",&c,&num);
if(c=='I') fun[i].input.push_back(num);
else fun[i].output.push_back(num);
}
}
cin>>s;//该电路运行的S次数据
for(int i=0;i<s;i++)
for(int j=1;j<=m;j++) scanf("%d",&input[i][j]);
int si=0, output=0;
for(int i=0;i<s;i++){//S行输出描述
scanf("%d",&si);
memset(gate,0,sizeof(gate));
//计算度i次运行每个门的输出
for(int w=1;w<=n;w++){
if(!gate[w]) get_output(input[i],w);
}
for(int j=0;j<si;j++){
scanf("%d",&output);
printf("%d ",fun[output].out);
}
printf("\n");
}
}
return 0;
}
照着y总视频
#include<iostream>
#include<sstream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int N=3010,M=N*5;
int m,n;
int w[N],f[N];
int h[N],e[N],ne[N],idx;
int q[N],d[N];
vector<int> in[M],out[M];
int get(char *str){
string names[]={"AND","OR","NOT","XOR","NAND","NOR"};
for(int i=0;i<6;i++){
if(names[i]==str){
return i;
}
}
return -1;
}
void add(int a,int b){
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
d[b]++;
}
bool topsort(){
int hh=0,tt=-1;
for(int i=1;i<=m+n;i++){
if(!d[i]){
q[++tt]=i;
}
}
while(hh<=tt){
int t=q[hh++];
for(int i=h[t];~i;i=ne[i]){
int j=e[i];
if(--d[j]==0){
q[++tt]=j;
}
}
}
return tt==n+m-1;
}
int main(){
int T;
cin>>T;
while(T--){
scanf("%d%d",&m,&n);
memset(h,-1,sizeof(h));
idx=0;
memset(d,0,sizeof d);
char str[100];
for(int i=1;i<=n;i++){
int cnt;
scanf("%s%d",str,&cnt);
f[m+i]=get(str);
while(cnt--){
scanf("%s",str);
int t=atoi(str+1);
if(str[0]=='I') add(t,m+i);
else add(m+t,m+i);
}
}
int Q;
scanf("%d",&Q);
for(int i=0;i<Q;i++){
in[i].clear();
for(int j=0;j<m;j++){
int x;
scanf("%d",&x);
in[i].push_back(x);
}
}
for(int i=0;i<Q;i++){
out[i].clear();
int cnt;
scanf("%d",&cnt);
while(cnt--){
int x;
scanf("%d",&x);
out[i].push_back(x);
}
}
if(!topsort()) puts("LOOP");
else{
for(int i=0;i<Q;i++){
for(int j=0;j<m;j++){
w[j+1]=in[i][j];
}
for(int j=m+1;j<=m+n;j++){
if(f[j]==0||f[j]==5) w[j]=1;
else w[j]=0;
}
for(int j=0;j<m+n;j++){
int t=q[j],v=w[t];
for(int k=h[t];~k;k=ne[k]){
int u=e[k];
if(f[u]==0) w[u]&=v;
else if(f[u]==1) w[u]|=v;
else if(f[u]==2) w[u]=!v;
else if(f[u]==3) w[u]^=v;
else if(f[u]==4) w[u]|=!v;
else w[u]&=!v;
}
}
for(auto x:out[i]) printf("%d ",w[m+x]);
puts("");
}
}
}
return 0;
}
啊啊啊啊好多算法不会用…
数据结构学了跟没学一样…