1 1089的点在注释里面,核心就是遍历任意两个人说谎,看结果是否满足题目要求
2 1090 是一道好题目, 考虑到了时间复杂度
通常想法是看清单中每一个物品 是否存在与其不能存放的物品 那么复杂度就为 M*O(G^2)*查找时间
可以看到无论怎样存储不相应关系优化查找时间都会超时的
💗: 换一个思路 我们注意到只有1000对不相应关系
那么我们不是检查每一个物品,而是检查每一个不相应关系是否在这个清单出现,那么时间复杂度降为O(N*M) 完美!
1089:
#include <bits/stdc++.h> using namespace std; const int N=107; int v[N],p[N]; int n; int ans[5]; int cnt; int main () { cin>>n; for (int i=1;i<=n;i++) { cin>>v[i]; p[i]=1; }
//p[i]=-1 表示第i个人是狼人 for (int i=1;i<n;i++) for (int j=i+1;j<=n;j++) { p[i]=-1; p[j]=-1; for (int k=1;k<=n;k++) if (p[abs(v[k])]*v[k]<0) { ans[++cnt]=k; if (cnt>3) break; } if (cnt==2&&p[ans[1]]+p[ans[2]]==0) { cout<<i<<" "<<j<<endl; return 0; } p[i]=1; p[j]=1; cnt=0; } cout<<"No Solution"<<endl; return 0; }
1090 : (我的时间只有23ms哦)
#include <bits/stdc++.h> using namespace std; const int N=1e4+7; struct node { int x; int y; }; node t[N]; int n; bool isok[N*10]; int m; bool check () { for (int i=1;i<=n;i++) if (isok[t[i].x]&&isok[t[i].y]) return 0; return 1; } int main () { scanf ("%d %d",&n,&m); for (int i=1;i<=n;i++) scanf ("%d %d",&t[i].x,&t[i].y); for (int i=1;i<=m;i++) { memset (isok,0,sizeof(isok)); int num; scanf ("%d",&num); for (int i=1;i<=num;i++) { int x; scanf ("%d",&x); isok[x]=1; } if (check()) puts("Yes"); else puts("No"); } return 0; }
抓住青春的尾巴。。。