CCF CSP 数字点亮人生 更新
2021.4.10 明天就考CSP了,我重新复习了之前的代码思路,我才发现,我这题写的TM是什么鬼,注释都不写,根本看不懂,后面又写了一份,带了些注释,应该会好理解一点
第一份 代码短,时间长
#include<bits/stdc++.h>
using namespace std;
enum{NOT,AND,OR,XOR,NAND,NOR
};
int M[3100][3100];
int N,m,k,T; //实际上m就是k,我懒得改了,不用在意
struct node{
int statu; //什么门
int out; //每个逻辑电路 输出值 或 输入的 值
};
node P[3100];//输入部分+逻辑电路部分
int in[3100]; //记录入度
int Tra(string s)
{
if(s=="NOT") return NOT;
if(s=="AND") return AND;
if(s=="OR") return OR;
if(s=="XOR") return XOR;
if(s=="NAND") return NAND;
if(s=="NOR") return NOR;
}
bool Judge_c()//判环
{
int sum=0;
stack<int> S;
for(int i=k+1;i<=T;i++)
if(in[i]==0)
S.push(i),sum++;
while(S.size()!=0)
{
int v=S.top();
S.pop();
for(int i=k+1;i<=T;i++)
if(M[v][i]==1)
{
in[i]--;
if(in[i]==0)
S.push(i),sum++;
}
}
if(sum==N)
return false;
else
return true;
}
void init() //同一电路下,只改变输出,每次更新输出后所用的初始化
{
for(int i=1;i<=T;i++)
P[i].out=-1;
}
void All_init() //更新电路 大初始化
{
for(int i=1;i<=T;i++)
{
P[i].out=-1;
in[i]=0;
for(int j=1;j<=T;j++)
M[i][j]=0;
}
}
int Count(string s) //计算 类似 I123 的123
{
int sum=0;
int t=1;
for(int i=s.size()-1;i>=1;i--)
sum+=(s[i]-'0')*t,t*=10;
return sum;
}
int find_ans(int num) //找到某个逻辑电路所对应的输出
{
if(P[num].out>=0)
{
return P[num].out;
}
int ans;
int w=1;
for(int i=1;i<=T;i++)
{
if(M[num][i])
{
int val=find_ans(i);
if(w) //第一次进去,直接赋值
{
ans=val;
w=0;
continue;
}
else //往后开始采用对应的操作
{
switch(P[num].statu){
case NOR:
case OR:
ans|= val;
break;
case NAND:
case AND:
ans&=val;
break;
case XOR:
ans^=val;
break;
}
}
}
}
switch(P[num].statu){ //对于最后取非的统一处理
case NOT:
case NAND:
case NOR:
ans=!ans;
default:
break;
}
P[num].out=ans;
return ans;
}
int Q;
int main()
{
cin>>Q;
while(Q--) //按提示处理输入,这部分命名 的变量有点随意
{
cin>>m>>N;
k=m;
T=k+N;
init();
string s,v;
int x;
for(int i=k+1;i<=T;i++)
{
cin>>s>>x;
P[i].statu=Tra(s);
while(x--)
{
cin>>v;
if(v[0]=='I')
{
M[i][Count(v)]=1;
}
else
{
int g=Count(v)+k;
M[i][g]=1;
in[g]++;
}
}
}
bool tag;
if(tag=Judge_c())
{
cout<<"LOOP"<<endl; //这里还得继续读入,不然后面的数字会当成下一个电路的输入
}
int S;
cin>>S;
cin.get();//去掉换行
ostringstream fcout;
for(int i=0;i<S;i++)
{
getline(cin,s);
fcout<<s<<" ";
}
int fn=-1;
istringstream fcin(fcout.str());
for(int i=0;i<S;i++)
{
cin>>x;
for(int j=1;j<=k;j++)
{
fcin>>P[j].out;
}
while(x--)
{
cin>>fn;
if(!tag)
cout<<find_ans(fn+k)<<" ";
}
if(!tag)
{
cout<<endl;
init();
}
}
All_init();
}
return 0;
}
第二份 代码长 时间短
#include<cstdio>
#include<iostream>
#include<vector>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cstdlib>
using namespace std;
struct Point{
int re;
char *s;
};
int Q;
vector<int> G[501];
Point A[501];
int AA[501];
int visit[501];
int a=1;
int out[501];
vector<int> input_p[501];
vector<int> input[10001];
vector<int> output[10001];
void process_op()
{
char *b,*c;
b=(char*)malloc(10);
c=(char*)malloc(10);
scanf("%s",b);
A[a].s=b;
int k;
cin>>k;
for(int i=1;i<=k;i++)
{
scanf("%s",c);
if(c[0]=='I')
{
int pon;
char p;
sscanf(c,"%c%d",&p,&pon);
input_p[a].push_back(pon);
}
else
{
int pon;
char p;
sscanf(c,"%c%d",&p,&pon);
out[pon]++;
G[a].push_back(pon);
}
}
getchar();
free(c);
a++;
}
int search(int po)
{
if(visit[po]==-1)
return 0;
visit[po]=1;
vector<int>::iterator it= G[po].begin();
int sum=0;
vector<int>k;
while(it<G[po].end())
{
if(count(G[po].begin(),G[po].end(),*it)!=1)
{
if(find(k.begin(),k.end(),*it)!=k.end())
{
it++;
continue;
}
else
{
k.push_back(*it);
}
}
if(visit[*it]==1)
return 1;
else
sum+=search(*it);
it++;
}
visit[po]=-1;
return sum;
}
bool judge(int n)
{
queue<int>Q;
for(int i=1;i<=n;i++)
if(!out[i])
Q.push(i);
int num=0;
while(!Q.empty())
{
int u=Q.front();
Q.pop();
num++;
for(int i=0;i<G[u].size();i++)
{
if((--out[G[u][i]])==0)
Q.push(G[u][i]);
}
}
return num!=n;
}
int calculate(int po,vector<int> &list)
{
if(AA[po])
return A[po].re;
AA[po]=1;
char *p=A[po].s;
if(!strcmp(p,"NOT"))
{
if(G[po].size())
{
int meta=G[po][0];
A[po].re=!calculate(meta,list);
}
else
{
A[po].re=!list[input_p[po][0]];
}
}
else if (!strcmp(p,"AND"))
{
int size=G[po].size();
vector<int> val;
for(int i=0;i<size;i++)
{
val.push_back(calculate(G[po][i],list));
}
if(input_p[po].size())
{
int k=input_p[po].size();
while(k>0)
val.push_back(list[input_p[po][--k]]);
}
int len=val.size();
A[po].re=val[0];
for(int i=1;i<len;i++)
{
A[po].re&=val[i];
}
}
else if (!strcmp(p,"OR"))
{
int size=G[po].size();
vector<int> val;
for(int i=0;i<size;i++)
{
val.push_back(calculate(G[po][i],list));
}
if(input_p[po].size())
{
int k=input_p[po].size();
while(k>0)
val.push_back(list[input_p[po][--k]]);
}
int len=val.size();
A[po].re=val[0];
for(int i=1;i<len;i++)
{
A[po].re|=val[i];
}
}
else if (!strcmp(p,"XOR"))
{
int size=G[po].size();
vector<int> val;
for(int i=0;i<size;i++)
{
val.push_back(calculate(G[po][i],list));
}
if(input_p[po].size())
{
int k=input_p[po].size();
while(k>0)
val.push_back(list[input_p[po][--k]]);
}
int len=val.size();
A[po].re=val[0];
for(int i=1;i<len;i++)
{
A[po].re^=val[i];
}
}
else if (!strcmp(p,"NAND"))
{
int size=G[po].size();
vector<int> val;
for(int i=0;i<size;i++)
{
val.push_back(calculate(G[po][i],list));
}
if(input_p[po].size())
{
int k=input_p[po].size();
while(k>0)
val.push_back(list[input_p[po][--k]]);
}
int len=val.size();
A[po].re=val[0];
for(int i=1;i<len;i++)
{
A[po].re&=val[i];
}
A[po].re=!A[po].re;
}
else if (!strcmp(p,"NOR"))
{
int size=G[po].size();
vector<int> val;
for(int i=0;i<size;i++)
{
val.push_back(calculate(G[po][i],list));
}
if(input_p[po].size())
{
int k=input_p[po].size();
while(k>0)
val.push_back(list[input_p[po][--k]]);
}
int len=val.size();
A[po].re=val[0];
for(int i=1;i<len;i++)
{
A[po].re|=val[i];
}
A[po].re=!A[po].re;
}
return A[po].re;
}
void clear()
{
for(int i=0;i<=500;i++)
{
G[i].clear();
input_p[i].clear();
out[i]=0;
free(A[i].s);
}
memset(A,0,sizeof(A));
memset(AA,0,sizeof(AA));
memset(visit,0,sizeof(visit));
for(int i=0;i<=10000;i++)
{
output[i].clear();
input[i].clear() ;
}
a=1;
}
int main()
{
cin>>Q;
while(Q--)
{
int M,N;
cin>>M>>N;
int NN=N;
while(NN--)
{
process_op();
}
int S;
cin>>S;
for(int i=1;i<=S;i++)
{
input[i].push_back(0);
for(int j=1;j<=M;j++)
{
int l;
cin>>l;
input[i].push_back(l);
}
}
for(int i=1;i<=S;i++)
{
int b,v;
cin>>b;
for(int j=1;j<=b;j++)
{
cin>>v;
output[i].push_back(v);
}
}
int sum=0;
for(int i=1;i<=N;i++)
sum+=search(i);
if(sum)
{
cout<<"LOOP"<<endl;
clear();
continue;
}
/*
if(judge(N))
{
cout<<"LOOP"<<endl;
clear();
continue;
}
*/
for(int i=1;i<=S;i++)
{
for(int j=1;j<=N;j++)
{
calculate(j,input[i]);
}
int len=output[i].size();
for(int j=0;j<len;j++)
{
cout<<(A[output[i][j]].re&1)<<" ";
}
cout<<endl;
memset(AA,0,sizeof(AA));
}
clear();
}
return 0;
}