$NOIP2003$ 题解报告
目录
$Luogu\ P1038$ 神经网络$(\ √\ )$
$Luogu\ P1039$ 侦探推理$(\ √\ )$
$Luogu\ P1040$ 加分二叉树$(\ √\ )$
$Luogu\ P1041$ 传染病控制$(\ √\ )$
$Luogu\ P1038$ 神经网络
这题直接按照题意模拟即可,注意一下输入层的$u$是没有意义的
1 #include<bits/stdc++.h> 2 #define ri register int 3 #define ll long long 4 #define rl register ll 5 #define go(i,a,b) for(ri i=a;i<=b;i++) 6 #define back(i,a,b) for(ri i=a;i>=b;i--) 7 #define g() getchar() 8 #define il inline 9 #define pf printf 10 #define mem(a,b) memset(a,b,sizeof(a)) 11 #define P pair<int,int> 12 #define mp make_pair 13 #define pb push_back 14 using namespace std; 15 il int fr(){ 16 ri w=0,q=1;char ch=g(); 17 while(ch<'0'||ch>'9'){if(ch=='-')q=-1;ch=g();} 18 while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=g(); 19 return w*q; 20 } 21 const int N=102; 22 int n,p,u[N],c[N],du[N],num; 23 queue<int>q; 24 vector<P>w[N]; 25 struct node{ 26 int id,as; 27 }ans[N]; 28 il bool cmp(node x,node y){return x.id<y.id;} 29 int main(){ 30 //freopen(".in","r",stdin); 31 //freopen(".out","w",stdout); 32 n=fr();p=fr(); 33 go(i,1,n){ 34 c[i]=fr(),u[i]=fr(); 35 if(c[i]>0)q.push(i); 36 else c[i]-=u[i]; 37 } 38 go(i,1,p){ 39 ri x=fr(),y=fr(),z=fr(); 40 w[x].pb(mp(y,z));du[y]++; 41 } 42 while(!q.empty()){ 43 ri p=q.front();q.pop(); 44 ri siz=w[p].size(); 45 //cout<<"p="<<p<<" c="<<c[p]<<endl; 46 if(siz==0&&c[p]>0)ans[++num]=(node){p,c[p]}; 47 go(i,0,siz-1){ 48 int to=w[p][i].first,W=w[p][i].second; 49 if(c[p]>0)c[to]+=W*c[p];du[to]--; 50 /*cout<<"to="<<to<<" c="<<c[to]<<endl; 51 cout<<"du="<<du[to]<<endl;*/ 52 if(du[to]==0)q.push(to); 53 } 54 } 55 if(num==0){puts("NULL");return 0;} 56 sort(ans+1,ans+1+num,cmp); 57 go(i,1,num)pf("%d %d\n",ans[i].id,ans[i].as); 58 return 0; 59 }
$Luogu\ P1039$ 侦探推理
恶心的字符串(我永远讨厌字符串)
枚举当前是星期几,罪犯是谁,然后判断是否合法。
1 #include<bits/stdc++.h> 2 #define ri register int 3 #define ll long long 4 #define rl register ll 5 #define go(i,a,b) for(ri i=a;i<=b;i++) 6 #define back(i,a,b) for(ri i=a;i>=b;i--) 7 #define g() getchar() 8 #define il inline 9 #define pf printf 10 #define mem(a,b) memset(a,b,sizeof(a)) 11 using namespace std; 12 il int fr(){ 13 ri w=0,q=1;char ch=g(); 14 while(ch<'0'||ch>'9'){if(ch=='-')q=-1;ch=g();} 15 while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=g(); 16 return w*q; 17 } 18 const int M=22; 19 const int P=102; 20 int m,n,p,w[P],lie[M],crime; 21 string name[M],say[P]; 22 string day[10]={"","Today is Monday","Today is Tuesday","Today is Wednesday","Today is Thursday","Today is Friday","Today is Saturday","Today is Sunday"}; 23 bool error; 24 il void sol(ri x,ri fake){ 25 if(lie[x]!=fake&&lie[x]){error=1;return;} 26 lie[x]=fake;return; 27 } 28 int main(){ 29 //freopen(".in","r",stdin); 30 //freopen(".out","w",stdout); 31 m=fr();n=fr();p=fr(); 32 go(i,1,m)cin>>name[i]; 33 go(i,1,p){ 34 string who;cin>>who; 35 who.erase(who.end()-1); 36 go(j,1,m)if(name[j]==who){w[i]=j;break;} 37 char ch=g(); 38 while(ch<'A'||ch>'Z')ch=g(); 39 while((ch>='A'&&ch<='Z')||ch==' '||(ch<='z'&&ch>='a'))say[i]+=ch,ch=g(); 40 } 41 go(d,1,7)go(id,1,m){ 42 mem(lie,0);error=0; 43 ri lier=0,un=0; 44 go(i,1,p){ 45 ri who=w[i];if(error)break; 46 if(say[i]=="I am guilty")sol(who,id==who?1:-1); 47 if(say[i]=="I am not guilty")sol(who,id==who?-1:1); 48 go(j,1,7)if(say[i]==day[j]){sol(who,j==d?1:-1);break;} 49 go(j,1,m){ 50 if(say[i]==name[j]+" is guilty")sol(who,id==j?1:-1); 51 if(say[i]==name[j]+" is not guilty")sol(who,id==j?-1:1); 52 } 53 } 54 if(error)continue; 55 go(i,1,m){ 56 if(lie[i]==0)un++; 57 if(lie[i]==-1)lier++; 58 } 59 if(n>=lier&&n<=lier+un){ 60 if(crime&&crime!=id){pf("Cannot Determine\n");return 0;} 61 crime=id; 62 } 63 } 64 if(!crime)pf("Impossible\n"); 65 cout<<name[crime]<<endl; 66 return 0; 67 }
$Luogu\ P1040$ 加分二叉树
设$f[l][r]$为从$l~r$的节点组成的树的最大分值,$dp$转移很简单
1 #include<bits/stdc++.h> 2 #define ri register int 3 #define ll long long 4 #define rl register ll 5 #define go(i,a,b) for(ri i=a;i<=b;i++) 6 #define back(i,a,b) for(ri i=a;i>=b;i--) 7 #define g() getchar() 8 #define il inline 9 #define pf printf 10 #define mem(a,b) memset(a,b,sizeof(a)) 11 using namespace std; 12 il int fr(){ 13 ri w=0,q=1;char ch=g(); 14 while(ch<'0'||ch>'9'){if(ch=='-')q=-1;ch=g();} 15 while(ch>='0'&&ch<='9')w=(w<<1)+(w<<3)+ch-'0',ch=g(); 16 return w*q; 17 } 18 const int N=32; 19 int n,rt[N][N]; 20 ll f[N][N]; 21 il ll work(ri l,ri r){ 22 if(l>r)return 1; 23 rl as; 24 if(f[l][r]==-1) 25 go(i,l,r){ 26 as=work(l,i-1)*work(i+1,r)+f[i][i]; 27 if(as>f[l][r])f[l][r]=as,rt[l][r]=i; 28 } 29 return f[l][r]; 30 } 31 il void out(ri l,ri r){ 32 if(l>r)return; 33 pf("%d ",rt[l][r]); 34 out(l,rt[l][r]-1);out(rt[l][r]+1,r); 35 return; 36 } 37 int main(){ 38 //freopen(".in","r",stdin); 39 //freopen(".out","w",stdout); 40 n=fr();mem(f,-1); 41 go(i,1,n)f[i][i]=(ll)fr(),rt[i][i]=i; 42 pf("%lld\n",work(1,n));out(1,n); 43 return 0; 44 }
$Luogu\ P1041$ 传染病控制
就……暴搜?
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=302; 4 int n,p,ans=300; 5 int father[N],depth[N]={0,1},dep[N][N]; 6 bool tag[N]; 7 void build(int x,int y){ 8 if(depth[y]) swap(x,y); 9 father[y]=x; 10 depth[y]=depth[x]+1; 11 dep[depth[y]][++dep[depth[y]][0]]=y; 12 return; 13 } 14 void dfs(int deep,int die){ 15 if(die>=ans) return; 16 int num=0,d[N]; 17 for(int i=1;i<=dep[deep][0];i++){ 18 tag[dep[deep][i]]=1; 19 if(!tag[father[dep[deep][i]]]) d[++num]=dep[deep][i],tag[dep[deep][i]]=0; 20 else tag[dep[deep][i]]=1; 21 } 22 if(num==0){ 23 ans=die; 24 return; 25 } 26 die+=num-1; 27 for(int i=1;i<=num;i++){ 28 tag[d[i]]=1; 29 dfs(deep+1,die); 30 tag[d[i]]=0; 31 } 32 return; 33 } 34 int main(){ 35 int x,y; 36 scanf("%d%d",&n,&p); 37 for(int i=1;i<=p;i++){ 38 scanf("%d%d",&x,&y); 39 build(x,y); 40 } 41 dfs(2,1); 42 printf("%d\n",ans); 43 return 0; 44 }