标签:ns2 类型 输入格式 std alt poi 条件 push 有一个
题目:My Bad
#include <iostream> #include <string> #include <cstring> #include <queue> using namespace std; const int N = 20; int n,g,u; int b; int input[100][2*N],output_from[N],door[N+10][N+10],cnt[N],temcnt[N];//第一维的1到n个表示来自于哪个输入,n+1到n+g+1个表示来自于哪个门 char door_class[N]; bool check(int keys[],int bad_door,int cas){//check用来检查坏的门的cas情况 memcpy(temcnt,cnt,sizeof cnt); bool ok=true; int f[n+g+10]; int hh=1,tt=n; int q[2*N]; //memset (f,0,sizeof f); for(int i=1;i<=g;i++){ if(door_class[i]==‘a‘){ f[i+n]=1; } else f[i+n]=0; } for(int i=1;i<=n;i++){ // cout<<keys[i]<<" "; f[i]=keys[i]; q[i]=i; } while(hh<=tt){ int t = q[hh++]; // cout<<t<<endl; // cout<<t<<endl; if(t==bad_door){ if(cas==2){ f[t]=!f[t]; } else f[t]=cas; } for(int i=1;i<=g;i++){ // cout<<door[t][i]<<endl; if(door[t][i]){ cnt[i]--; // cout<<door_class[i]<<endl; if(door_class[i]==‘a‘){ if(f[t]==0){ f[i+n]=0; } } else if(door_class[i]==‘o‘){ if(f[t]==1){ f[i+n]=1; } } else if(door_class[i]==‘x‘){ f[i+n]=f[i+n]^f[t]; } else f[i+n]=!f[t]; if(cnt[i]==0){ //q.push(i+n); q[++tt]=i+n; } } } } memcpy(cnt,temcnt,sizeof cnt); for(int i=1;i<=u;i++){ if(f[output_from[i]+n]!=keys[i+n]){ return false; } } return true; } void work(int t){ bool ok=true; for(int i=1;i<=b;i++){ if(!check(input[i],-100,-1)){ ok=false; break; } } // cout<<ok<<endl; if(ok){ cout<<"Case "<<t<<": No faults detected"<<endl; } else{ int bad_num=0; int bad_door=-1; int bad_case=-1; int i,j,k; for(j=1;j<=g;j++){ for(k=0;k<=2;k++){ ok=true; for(i=1;i<=b;i++){ if(!check(input[i],j+n,k)){ ok=false; break; } } if(ok) { bad_door=j; bad_case=k; bad_num++; } } } // cout<<bad_case<<" "<<bad_door<<endl; if(bad_num>1){ cout<<"Case "<<t<<": Unable to totally classify the failure"<<endl; } else if(bad_case==2){ cout<<"Case "<<t<<": Gate "<<bad_door<<" is failing; output inverted"<<endl; } else if(bad_case==1){ cout<<"Case "<<t<<": Gate "<<bad_door<<" is failing; output stuck at 1"<<endl; } else { cout<<"Case "<<t<<": Gate "<<bad_door<<" is failing; output stuck at 0"<<endl; } } } int main(){ ios::sync_with_stdio(false); int t=1; while(cin>>n>>g>>u&&n){ memset(door,0,sizeof door); //memset (output_from,0,sizeof output_from); memset (cnt,0,sizeof cnt); for(int i=1;i<=g;i++){ char c; cin>>c; door_class[i]=c; if(c==‘o‘||c==‘a‘||c==‘x‘){ string s1,s2; cin>>s1>>s2; // cout<<s1<<s2<<endl; int num1=0,num2=0; for(int j=1;j<s1.length();j++){ num1=num1*10; num1+=s1[j]-‘0‘; } for(int j=1;j<s2.length();j++){ num2=num2*10; num2+=s2[j]-‘0‘; } if(s1[0]==‘i‘)door[num1][i]=1; else door[num1+n][i]=1; if(s2[0]==‘i‘)door[num2][i]=1; else door[num2+n][i]=1; cnt[i]+=2; // cout<<cnt[i]<<endl; } else{ string s1; cin>>s1; int num=0; for(int j=1;j<s1.length();j++){ num=num*10; num+=s1[j]-‘0‘; } if(s1[0]==‘i‘)door[num][i]=1; else door[num+n][i]=1; cnt[i]++; } } for(int i=1;i<=u;i++){ int ui; cin>>ui; output_from[i]=ui; } cin>>b; for(int i=1;i<=b;i++){ for(int j=1;j<=n+u;j++){ int tem; cin>>tem; input[i][j]=tem; } } work(t); t++; } }
code2:(ac的代码)大佬用前向星就ac tql 详细给出注释
#include<iostream> #include<string> #include<string.h> #include<stdlib.h> using namespace std; struct dat_edge { int aim,last; }edge[201]; int n,m,k,inde[101],coun[101],tmp_coun[101],pl[101],len_edge,num_key,key[300][101]; char kind[101];//kind保存门的种类 void insert_edge(int x,int y)//从x到y有一个边比如i0=>m1(这里是前向星) { len_edge++; edge[len_edge].aim=y; edge[len_edge].last=pl[x]; pl[x]=len_edge; } void init(int o,string z)//o表示在处理第几个门 { int p,i,num; string t; p=1; z+=‘ ‘;//为了以后处理方便 for(i=1;i<z.length();i++)//例如z=" i1 i2 " if(z[i]==‘ ‘) { t=z.substr(p,i-p);//取一个来源 if(t[0]==‘i‘)//来自于输入 num=0; else num=n; if(t.length()==2) num+=t[1]-‘0‘;//来自于第几个门或者输入 else { num+=(t[1]-‘0‘)*10+t[2]-‘0‘;//处理10以上的标签 } coun[o]++;//记录o这个门的输入个数 insert_edge(num,o);//输入的编号从1到n,门的编号从n到n+m,输出编号n+m到n+m+k p=i+1; } } bool solve(int key[],int poi,int sta)//key表示第i组输入和输出,poi表示,sta表示所属情况 { int i,p,o,w,tmp,que[101],f[101]; for(i=1;i<=n+m+k;i++) { f[i]=0;//f数组保存每个节点的状态要么是1要么是0 } for(i=1;i<=n;i++) f[i]=key[i]; for(i=1;i<=m;i++) { if(kind[i]==‘a‘)//如果当前门是与门 f[i+n]=1; else f[i+n]=0; } o=n;w=0;//w表示对头,o表示队尾 for(i=1;i<=n;i++) que[i]=i;//先把所有输入都入队 while(w<o) { w++; if(que[w]==poi)//如果当前处理到第poi个门 { if(sta==2) f[que[w]]=!f[que[w]];//第二个状态就翻转 else f[que[w]]=sta;//第0个状态就取0,第三个状态就取1 } p=pl[que[w]]; while(p!=-1)//遍历每一个出边 { coun[edge[p].aim]--;//指向的顶点的入度减一 if(coun[edge[p].aim]==0) { que[++o]=edge[p].aim;//如果指向的顶点计算完了就把它入队 } tmp=edge[p].aim; if(kind[tmp-n]==‘a‘)//出边必然指向门 { if(f[que[w]]==0) f[tmp]=0; } else if(kind[tmp-n]==‘o‘) { if(f[que[w]]==1) f[tmp]=1; } else if(kind[tmp-n]==‘x‘) { f[tmp]=f[tmp]^f[que[w]]; } else { f[tmp]=!f[que[w]]; } p=edge[p].last; } } for(i=1;i<=n+m+k;i++) coun[i]=tmp_coun[i]; for(i=1;i<=k;i++) { if(f[inde[i]+n]!=key[n+i]) return false; } return true; } void work(int t) { int i,j,p,ans1,ans2,coun_ans; bool ok=true; for(i=1;i<=num_key;i++)//遍历每一次询问 { if(!solve(key[i],-1,-1))//bfs判断方案的可行性 { ok=false; break; } } if(ok) { cout<<"Case "<<t<<": No faults detected\n"; return; } ans1=ans2=coun_ans=0; for(i=1;i<=m;i++)//枚举每个门 { for(j=0;j<=2;j++)//枚举三种情况 { ok=true; for(p=1;p<=num_key;p++)//枚举每一种给出的情况 { ok=solve(key[p],i+n,j);//枚举第i个门第j种情况 if(!ok) break; } if(ok)//如果第i个门出现了第j个情况并且当前样例在这个情况下合理 { ans1=i;//ans1表示第几个门 ans2=j;//ans2表示第几种情况 coun_ans++;//count_ans>1表示情况有多种就没有办法确定 } } } if(coun_ans!=1) { cout<<"Case "<<t<<": Unable to totally classify the failure\n"; return; } if(ans2==2) { cout<<"Case "<<t<<": Gate "<<ans1<<" is failing; output inverted\n"; return; } if(ans2==0) { cout<<"Case "<<t<<": Gate "<<ans1<<" is failing; output stuck at 0\n"; return; } if(ans2==1) { cout<<"Case "<<t<<": Gate "<<ans1<<" is failing; output stuck at 1\n"; return; } } int main() { int t,i,j; string z; t=0;//t 用来记录第几组测试数据 while(cin>>n>>m>>k && n+m+k!=0)//n m k 分别代表输入数量,门的数量和输出数量 { t++; memset(coun,0,sizeof(coun));//coun 表示每个顶点的输入个数 len_edge=-1;//len_edge表示边的个数(把每一对输入输出抽象为一个边)把问题抽象为一个图,把每个门包括输入输出点都抽象为顶点 for(i=1;i<=n+m+k;i++) pl[i]=-1;//pl保存该顶点的出边 for(i=1;i<=m;i++)//输入m个门以及它的数据来源 { cin>>kind[i];//kind保存该门的种类 getline(cin,z); init(i+n,z);//可以初始化为一个图 } for(i=1;i<=n+m+k;i++) tmp_coun[i]=coun[i];//临时保存一下每个顶点的输入个数 for(i=1;i<=k;i++) cin>>inde[i];//输出来自于哪个门 cin>>num_key;//判别条件的个数 for(i=1;i<=num_key;i++) for(j=1;j<=n+k;j++) cin>>key[i][j];//第i个询问的记录 work(t); } return 0; }
标签:ns2 类型 输入格式 std alt poi 条件 push 有一个
原文地址:https://www.cnblogs.com/kstranger/p/12242442.html